| /** |
| * @fileoverview Tests for lazy_accessor.js. |
| */ |
| goog.module('protobuf.binary.LazyAccessorTest'); |
| |
| goog.setTestOnly(); |
| |
| const ByteString = goog.require('protobuf.ByteString'); |
| const Int64 = goog.require('protobuf.Int64'); |
| const InternalMessage = goog.require('protobuf.binary.InternalMessage'); |
| const LazyAccessor = goog.require('protobuf.binary.LazyAccessor'); |
| const TestMessage = goog.require('protobuf.testing.binary.TestMessage'); |
| // Note to the reader: |
| // Since the lazy accessor behavior changes with the checking level some of the |
| // tests in this file have to know which checking level is enable to make |
| // correct assertions. |
| const {CHECK_BOUNDS, CHECK_CRITICAL_STATE, CHECK_CRITICAL_TYPE, CHECK_TYPE, MAX_FIELD_NUMBER} = goog.require('protobuf.internal.checks'); |
| |
| /** |
| * @param {...number} bytes |
| * @return {!ArrayBuffer} |
| */ |
| function createArrayBuffer(...bytes) { |
| return new Uint8Array(bytes).buffer; |
| } |
| |
| describe('LazyAccessor', () => { |
| it('encodes none for the empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); |
| expect(accessor.serialize()).toEqual(new ArrayBuffer(0)); |
| }); |
| |
| it('encodes and decodes max field number', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x0F, 0x01)); |
| expect(accessor.getBoolWithDefault(MAX_FIELD_NUMBER)).toBe(true); |
| accessor.setBool(MAX_FIELD_NUMBER, false); |
| expect(accessor.serialize()) |
| .toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x0F, 0x00)); |
| }); |
| |
| it('uses the default pivot point', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); |
| expect(accessor.getPivot()).toBe(24); |
| }); |
| |
| it('makes the pivot point configurable', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0), 50); |
| expect(accessor.getPivot()).toBe(50); |
| }); |
| }); |
| |
| describe('LazyAccessor hasFieldNumber', () => { |
| it('returns false for empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); |
| expect(accessor.hasFieldNumber(1)).toBe(false); |
| }); |
| |
| it('returns true for non-empty input', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.hasFieldNumber(1)).toBe(true); |
| }); |
| |
| it('returns false for empty array', () => { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setPackedBoolIterable(1, []); |
| expect(accessor.hasFieldNumber(1)).toBe(false); |
| }); |
| |
| it('returns true for non-empty array', () => { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setPackedBoolIterable(1, [true]); |
| expect(accessor.hasFieldNumber(1)).toBe(true); |
| }); |
| |
| it('updates value after write', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); |
| expect(accessor.hasFieldNumber(1)).toBe(false); |
| accessor.setBool(1, false); |
| expect(accessor.hasFieldNumber(1)).toBe(true); |
| }); |
| }); |
| |
| describe('LazyAccessor clear field does', () => { |
| it('clear the field set', () => { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setBool(1, true); |
| accessor.clearField(1); |
| |
| expect(accessor.hasFieldNumber(1)).toEqual(false); |
| expect(accessor.serialize()).toEqual(new ArrayBuffer(0)); |
| expect(accessor.getBoolWithDefault(1)).toEqual(false); |
| }); |
| |
| it('clear the field decoded', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.clearField(1); |
| |
| expect(accessor.hasFieldNumber(1)).toEqual(false); |
| expect(accessor.serialize()).toEqual(new ArrayBuffer(0)); |
| expect(accessor.getBoolWithDefault(1)).toEqual(false); |
| }); |
| |
| it('clear the field read', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getBoolWithDefault(1)).toEqual(true); |
| accessor.clearField(1); |
| |
| expect(accessor.hasFieldNumber(1)).toEqual(false); |
| expect(accessor.serialize()).toEqual(new ArrayBuffer(0)); |
| expect(accessor.getBoolWithDefault(1)).toEqual(false); |
| }); |
| |
| it('clear set and copied fields without affecting the old', () => { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setBool(1, true); |
| |
| const clonedAccessor = accessor.shallowCopy(); |
| clonedAccessor.clearField(1); |
| |
| expect(accessor.hasFieldNumber(1)).toEqual(true); |
| expect(accessor.getBoolWithDefault(1)).toEqual(true); |
| expect(clonedAccessor.hasFieldNumber(1)).toEqual(false); |
| expect(clonedAccessor.serialize()).toEqual(new ArrayBuffer(0)); |
| expect(clonedAccessor.getBoolWithDefault(1)).toEqual(false); |
| }); |
| |
| it('clear decoded and copied fields without affecting the old', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| |
| const clonedAccessor = accessor.shallowCopy(); |
| clonedAccessor.clearField(1); |
| |
| expect(accessor.hasFieldNumber(1)).toEqual(true); |
| expect(accessor.getBoolWithDefault(1)).toEqual(true); |
| expect(clonedAccessor.hasFieldNumber(1)).toEqual(false); |
| expect(clonedAccessor.serialize()).toEqual(new ArrayBuffer(0)); |
| expect(clonedAccessor.getBoolWithDefault(1)).toEqual(false); |
| }); |
| |
| it('clear read and copied fields without affecting the old', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getBoolWithDefault(1)).toEqual(true); |
| |
| const clonedAccessor = accessor.shallowCopy(); |
| clonedAccessor.clearField(1); |
| |
| expect(accessor.hasFieldNumber(1)).toEqual(true); |
| expect(accessor.getBoolWithDefault(1)).toEqual(true); |
| expect(clonedAccessor.hasFieldNumber(1)).toEqual(false); |
| expect(clonedAccessor.serialize()).toEqual(new ArrayBuffer(0)); |
| expect(clonedAccessor.getBoolWithDefault(1)).toEqual(false); |
| }); |
| |
| it('clear the max field number', () => { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setBool(MAX_FIELD_NUMBER, true); |
| |
| accessor.clearField(MAX_FIELD_NUMBER); |
| |
| expect(accessor.hasFieldNumber(MAX_FIELD_NUMBER)).toEqual(false); |
| expect(accessor.getBoolWithDefault(MAX_FIELD_NUMBER)).toEqual(false); |
| }); |
| }); |
| |
| describe('LazyAccessor shallow copy does', () => { |
| it('work for singular fields', () => { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setBool(1, true); |
| accessor.setBool(MAX_FIELD_NUMBER, true); |
| const clonedAccessor = accessor.shallowCopy(); |
| expect(clonedAccessor.getBoolWithDefault(1)).toEqual(true); |
| expect(clonedAccessor.getBoolWithDefault(MAX_FIELD_NUMBER)).toEqual(true); |
| |
| accessor.setBool(1, false); |
| accessor.setBool(MAX_FIELD_NUMBER, false); |
| expect(clonedAccessor.getBoolWithDefault(1)).toEqual(true); |
| expect(clonedAccessor.getBoolWithDefault(MAX_FIELD_NUMBER)).toEqual(true); |
| }); |
| |
| it('work for repeated fields', () => { |
| const accessor = LazyAccessor.createEmpty(); |
| |
| accessor.addUnpackedBoolIterable(2, [true, true]); |
| |
| const clonedAccessor = accessor.shallowCopy(); |
| |
| // Modify a repeated field after clone |
| accessor.addUnpackedBoolElement(2, true); |
| |
| const array = Array.from(clonedAccessor.getRepeatedBoolIterable(2)); |
| expect(array).toEqual([true, true]); |
| }); |
| |
| it('work for repeated fields', () => { |
| const accessor = LazyAccessor.createEmpty(); |
| |
| accessor.addUnpackedBoolIterable(2, [true, true]); |
| |
| const clonedAccessor = accessor.shallowCopy(); |
| |
| // Modify a repeated field after clone |
| accessor.addUnpackedBoolElement(2, true); |
| |
| const array = Array.from(clonedAccessor.getRepeatedBoolIterable(2)); |
| expect(array).toEqual([true, true]); |
| }); |
| |
| it('return the correct bytes after serialization', () => { |
| const bytes = createArrayBuffer(0x08, 0x01, 0x10, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes, /* pivot= */ 1); |
| const clonedAccessor = accessor.shallowCopy(); |
| |
| accessor.setBool(1, false); |
| |
| expect(clonedAccessor.getBoolWithDefault(1)).toEqual(true); |
| expect(clonedAccessor.serialize()).toEqual(bytes); |
| }); |
| }); |
| |
| describe('LazyAccessor for singular boolean does', () => { |
| it('return false for the empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); |
| expect(accessor.getBoolWithDefault( |
| /* fieldNumber= */ 1)) |
| .toBe(false); |
| }); |
| |
| it('return the value from the input', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getBoolWithDefault( |
| /* fieldNumber= */ 1)) |
| .toBe(true); |
| }); |
| |
| it('encode the value from the input', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.serialize()).toEqual(bytes); |
| }); |
| |
| it('encode the value from the input after read', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.getBoolWithDefault( |
| /* fieldNumber= */ 1); |
| expect(accessor.serialize()).toEqual(bytes); |
| }); |
| |
| it('return the value from multiple inputs', () => { |
| const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getBoolWithDefault( |
| /* fieldNumber= */ 1)) |
| .toBe(false); |
| }); |
| |
| it('encode the value from multiple inputs', () => { |
| const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.serialize()).toEqual(bytes); |
| }); |
| |
| it('encode the value from multiple inputs after read', () => { |
| const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.getBoolWithDefault(/* fieldNumber= */ 1); |
| expect(accessor.serialize()).toEqual(bytes); |
| }); |
| |
| it('return the value from setter', () => { |
| const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.setBool(1, true); |
| expect(accessor.getBoolWithDefault( |
| /* fieldNumber= */ 1)) |
| .toBe(true); |
| }); |
| |
| it('encode the value from setter', () => { |
| const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const newBytes = createArrayBuffer(0x08, 0x01); |
| accessor.setBool(1, true); |
| expect(accessor.serialize()).toEqual(newBytes); |
| }); |
| |
| it('return the bool value from cache', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getBoolWithDefault( |
| /* fieldNumber= */ 1)) |
| .toBe(true); |
| // Make sure the value is cached. |
| bytes[1] = 0x00; |
| expect(accessor.getBoolWithDefault( |
| /* fieldNumber= */ 1)) |
| .toBe(true); |
| }); |
| |
| it('fail when getting bool value with other wire types', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( |
| 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); |
| if (CHECK_CRITICAL_TYPE) { |
| expect(() => { |
| accessor.getBoolWithDefault(/* fieldNumber= */ 1); |
| }).toThrowError('Expected wire type: 0 but found: 1'); |
| } else { |
| // Note in unchecked mode we produce invalid output for invalid inputs. |
| // This test just documents our behavior in those cases. |
| // These values might change at any point and are not considered |
| // what the implementation should be doing here. |
| expect(accessor.getBoolWithDefault( |
| /* fieldNumber= */ 1)) |
| .toBe(true); |
| } |
| }); |
| |
| it('fail when setting bool value with out-of-range field number', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); |
| if (CHECK_TYPE) { |
| expect(() => accessor.setBool(MAX_FIELD_NUMBER + 1, false)) |
| .toThrowError('Field number is out of range: 536870912'); |
| } else { |
| // Note in unchecked mode we produce invalid output for invalid inputs. |
| // This test just documents our behavior in those cases. |
| // These values might change at any point and are not considered |
| // what the implementation should be doing here. |
| accessor.setBool(MAX_FIELD_NUMBER + 1, false); |
| expect(accessor.getBoolWithDefault(MAX_FIELD_NUMBER + 1)).toBe(false); |
| } |
| }); |
| |
| it('fail when setting bool value with number value', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); |
| const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); |
| if (CHECK_CRITICAL_TYPE) { |
| expect(() => accessor.setBool(1, fakeBoolean)) |
| .toThrowError('Must be a boolean, but got: 2'); |
| } else { |
| // Note in unchecked mode we produce invalid output for invalid inputs. |
| // This test just documents our behavior in those cases. |
| // These values might change at any point and are not considered |
| // what the implementation should be doing here. |
| accessor.setBool(1, fakeBoolean); |
| expect(accessor.getBoolWithDefault( |
| /* fieldNumber= */ 1)) |
| .toBe(2); |
| } |
| }); |
| }); |
| |
| describe('LazyAccessor for singular message does', () => { |
| it('return message from the input', () => { |
| const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const msg = accessor.getMessageOrNull(1, TestMessage.instanceCreator); |
| expect(msg.getBoolWithDefault(1, false)).toBe(true); |
| }); |
| |
| it('return message from the input when pivot is set', () => { |
| const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes, /* pivot= */ 0); |
| const msg = accessor.getMessageOrNull(1, TestMessage.instanceCreator); |
| expect(msg.getBoolWithDefault(1, false)).toBe(true); |
| }); |
| |
| it('encode message from the input', () => { |
| const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.serialize()).toEqual(bytes); |
| }); |
| |
| it('encode message from the input after read', () => { |
| const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.getMessageOrNull(1, TestMessage.instanceCreator); |
| expect(accessor.serialize()).toEqual(bytes); |
| }); |
| |
| it('return message from multiple inputs', () => { |
| const bytes = |
| createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x10, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const msg = accessor.getMessageOrNull(1, TestMessage.instanceCreator); |
| expect(msg.getBoolWithDefault(1, false)).toBe(true); |
| expect(msg.getBoolWithDefault(2, false)).toBe(true); |
| }); |
| |
| it('encode message from multiple inputs', () => { |
| const bytes = |
| createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x10, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.serialize()).toEqual(bytes); |
| }); |
| |
| it('encode message merged from multiple inputs after read', () => { |
| const bytes = |
| createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x10, 0x01); |
| const expected = createArrayBuffer(0x0A, 0x04, 0x08, 0x01, 0x10, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.getMessageOrNull(1, TestMessage.instanceCreator); |
| expect(accessor.serialize()).toEqual(expected); |
| }); |
| |
| it('return null for generic accessor', () => { |
| const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const accessor1 = accessor.getMessageAccessorOrNull(7); |
| expect(accessor1).toBe(null); |
| }); |
| |
| it('return null for generic accessor when pivot is set', () => { |
| const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const accessor1 = accessor.getMessageAccessorOrNull(7, /* pivot= */ 0); |
| expect(accessor1).toBe(null); |
| }); |
| |
| it('return generic accessor from the input', () => { |
| const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const accessor1 = accessor.getMessageAccessorOrNull(1); |
| expect(accessor1.getBoolWithDefault(1, false)).toBe(true); |
| // Second call returns a new instance, isn't cached. |
| const accessor2 = accessor.getMessageAccessorOrNull(1); |
| expect(accessor2.getBoolWithDefault(1, false)).toBe(true); |
| expect(accessor2).not.toBe(accessor1); |
| }); |
| |
| it('return generic accessor from the cached input', () => { |
| const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const wrappedMessage = |
| accessor.getMessageOrNull(1, TestMessage.instanceCreator); |
| |
| // Returns accessor from the cached wrapper instance. |
| const accessor1 = accessor.getMessageAccessorOrNull(1); |
| expect(accessor1.getBoolWithDefault(1, false)).toBe(true); |
| expect(accessor1).toBe( |
| (/** @type {!InternalMessage} */ (wrappedMessage)).internalGetKernel()); |
| |
| // Second call returns exact same instance. |
| const accessor2 = accessor.getMessageAccessorOrNull(1); |
| expect(accessor2.getBoolWithDefault(1, false)).toBe(true); |
| expect(accessor2).toBe( |
| (/** @type {!InternalMessage} */ (wrappedMessage)).internalGetKernel()); |
| expect(accessor2).toBe(accessor1); |
| }); |
| |
| it('return message from setter', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); |
| const subaccessor = LazyAccessor.fromArrayBuffer(bytes); |
| const submsg1 = new TestMessage(subaccessor); |
| accessor.setMessage(1, submsg1); |
| const submsg2 = accessor.getMessage(1, TestMessage.instanceCreator); |
| expect(submsg1).toBe(submsg2); |
| }); |
| |
| it('encode message from setter', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); |
| const subaccessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); |
| const subsubaccessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); |
| const subsubmsg = new TestMessage(subsubaccessor); |
| subaccessor.setMessage(1, subsubmsg); |
| const submsg = new TestMessage(subaccessor); |
| accessor.setMessage(1, submsg); |
| const expected = createArrayBuffer(0x0A, 0x04, 0x0A, 0x02, 0x08, 0x01); |
| expect(accessor.serialize()).toEqual(expected); |
| }); |
| |
| it('encode message with multiple submessage from setter', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); |
| const subaccessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); |
| const subsubaccessor1 = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); |
| const subsubaccessor2 = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x02)); |
| |
| const subsubmsg1 = new TestMessage(subsubaccessor1); |
| const subsubmsg2 = new TestMessage(subsubaccessor2); |
| |
| subaccessor.setMessage(1, subsubmsg1); |
| subaccessor.setMessage(2, subsubmsg2); |
| |
| const submsg = new TestMessage(subaccessor); |
| accessor.setMessage(1, submsg); |
| |
| const expected = createArrayBuffer( |
| 0x0A, 0x08, 0x0A, 0x02, 0x08, 0x01, 0x12, 0x02, 0x08, 0x02); |
| expect(accessor.serialize()).toEqual(expected); |
| }); |
| |
| it('leave hasFieldNumber unchanged after getMessageOrNull', () => { |
| const accessor = LazyAccessor.createEmpty(); |
| expect(accessor.hasFieldNumber(1)).toBe(false); |
| expect(accessor.getMessageOrNull(1, TestMessage.instanceCreator)) |
| .toBe(null); |
| expect(accessor.hasFieldNumber(1)).toBe(false); |
| }); |
| |
| it('serialize changes to submessages made with getMessageOrNull', () => { |
| const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); |
| const accessor = LazyAccessor.fromArrayBuffer(intTwoBytes); |
| const mutableSubMessage = |
| accessor.getMessageOrNull(1, TestMessage.instanceCreator); |
| mutableSubMessage.setInt32(1, 10); |
| const intTenBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x0A); |
| expect(accessor.serialize()).toEqual(intTenBytes); |
| }); |
| |
| it('serialize additions to submessages made with getMessageOrNull', () => { |
| const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); |
| const accessor = LazyAccessor.fromArrayBuffer(intTwoBytes); |
| const mutableSubMessage = |
| accessor.getMessageOrNull(1, TestMessage.instanceCreator); |
| mutableSubMessage.setInt32(2, 3); |
| // Sub message contains the original field, plus the new one. |
| expect(accessor.serialize()) |
| .toEqual(createArrayBuffer(0x0A, 0x04, 0x08, 0x02, 0x10, 0x03)); |
| }); |
| |
| it('fail with getMessageOrNull if immutable message exist in cache', () => { |
| const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); |
| const accessor = LazyAccessor.fromArrayBuffer(intTwoBytes); |
| |
| const readOnly = accessor.getMessage(1, TestMessage.instanceCreator); |
| if (CHECK_TYPE) { |
| expect(() => accessor.getMessageOrNull(1, TestMessage.instanceCreator)) |
| .toThrow(); |
| } else { |
| const mutableSubMessage = |
| accessor.getMessageOrNull(1, TestMessage.instanceCreator); |
| // The instance returned by getMessageOrNull is the exact same instance. |
| expect(mutableSubMessage).toBe(readOnly); |
| |
| // Serializing the submessage does not write the changes |
| mutableSubMessage.setInt32(1, 0); |
| expect(accessor.serialize()).toEqual(intTwoBytes); |
| } |
| }); |
| |
| it('change hasFieldNumber after getMessageAttach', () => { |
| const accessor = LazyAccessor.createEmpty(); |
| expect(accessor.hasFieldNumber(1)).toBe(false); |
| expect(accessor.getMessageAttach(1, TestMessage.instanceCreator)) |
| .not.toBe(null); |
| expect(accessor.hasFieldNumber(1)).toBe(true); |
| }); |
| |
| it('change hasFieldNumber after getMessageAttach when pivot is set', () => { |
| const accessor = LazyAccessor.createEmpty(); |
| expect(accessor.hasFieldNumber(1)).toBe(false); |
| expect(accessor.getMessageAttach( |
| 1, TestMessage.instanceCreator, /* pivot= */ 1)) |
| .not.toBe(null); |
| expect(accessor.hasFieldNumber(1)).toBe(true); |
| }); |
| |
| it('serialize submessages made with getMessageAttach', () => { |
| const accessor = LazyAccessor.createEmpty(); |
| const mutableSubMessage = |
| accessor.getMessageAttach(1, TestMessage.instanceCreator); |
| mutableSubMessage.setInt32(1, 10); |
| const intTenBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x0A); |
| expect(accessor.serialize()).toEqual(intTenBytes); |
| }); |
| |
| it('serialize additions to submessages using getMessageAttach', () => { |
| const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); |
| const accessor = LazyAccessor.fromArrayBuffer(intTwoBytes); |
| const mutableSubMessage = |
| accessor.getMessageAttach(1, TestMessage.instanceCreator); |
| mutableSubMessage.setInt32(2, 3); |
| // Sub message contains the original field, plus the new one. |
| expect(accessor.serialize()) |
| .toEqual(createArrayBuffer(0x0A, 0x04, 0x08, 0x02, 0x10, 0x03)); |
| }); |
| |
| it('fail with getMessageAttach if immutable message exist in cache', () => { |
| const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); |
| const accessor = LazyAccessor.fromArrayBuffer(intTwoBytes); |
| |
| const readOnly = accessor.getMessage(1, TestMessage.instanceCreator); |
| if (CHECK_TYPE) { |
| expect(() => accessor.getMessageAttach(1, TestMessage.instanceCreator)) |
| .toThrow(); |
| } else { |
| const mutableSubMessage = |
| accessor.getMessageAttach(1, TestMessage.instanceCreator); |
| // The instance returned by getMessageOrNull is the exact same instance. |
| expect(mutableSubMessage).toBe(readOnly); |
| |
| // Serializing the submessage does not write the changes |
| mutableSubMessage.setInt32(1, 0); |
| expect(accessor.serialize()).toEqual(intTwoBytes); |
| } |
| }); |
| |
| it('read default message return empty message with getMessage', () => { |
| const bytes = new ArrayBuffer(0); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getMessage(1, TestMessage.instanceCreator)).toBeTruthy(); |
| expect(accessor.getMessage(1, TestMessage.instanceCreator).serialize()) |
| .toEqual(bytes); |
| }); |
| |
| it('read default message return null with getMessageOrNull', () => { |
| const bytes = new ArrayBuffer(0); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getMessageOrNull(1, TestMessage.instanceCreator)) |
| .toBe(null); |
| }); |
| |
| it('read message preserve reference equality', () => { |
| const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const msg1 = accessor.getMessageOrNull(1, TestMessage.instanceCreator); |
| const msg2 = accessor.getMessageOrNull(1, TestMessage.instanceCreator); |
| const msg3 = accessor.getMessageAttach(1, TestMessage.instanceCreator); |
| expect(msg1).toBe(msg2); |
| expect(msg1).toBe(msg3); |
| }); |
| |
| it('fail when getting message with other wire types', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); |
| expect(() => accessor.getMessageOrNull(1, TestMessage.instanceCreator)) |
| .toThrow(); |
| }); |
| |
| it('fail when submessage has incomplete data', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x08)); |
| expect(() => accessor.getMessageOrNull(1, TestMessage.instanceCreator)) |
| .toThrow(); |
| }); |
| |
| it('fail when mutable submessage has incomplete data', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x08)); |
| expect(() => accessor.getMessageAttach(1, TestMessage.instanceCreator)) |
| .toThrow(); |
| }); |
| |
| it('fail when getting message with null instance constructor', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x02, 0x08, 0x01)); |
| const nullMessage = /** @type {function(!LazyAccessor):!TestMessage} */ |
| (/** @type {*} */ (null)); |
| expect(() => accessor.getMessageOrNull(1, nullMessage)).toThrow(); |
| }); |
| |
| it('fail when setting message value with null value', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); |
| const fakeMessage = /** @type {!TestMessage} */ (/** @type {*} */ (null)); |
| if (CHECK_CRITICAL_TYPE) { |
| expect(() => accessor.setMessage(1, fakeMessage)) |
| .toThrowError('Given value is not a message instance: null'); |
| } else { |
| // Note in unchecked mode we produce invalid output for invalid inputs. |
| // This test just documents our behavior in those cases. |
| // These values might change at any point and are not considered |
| // what the implementation should be doing here. |
| accessor.setMessage(1, fakeMessage); |
| expect(accessor.getMessageOrNull( |
| /* fieldNumber= */ 1, TestMessage.instanceCreator)) |
| .toBeNull(); |
| } |
| }); |
| }); |
| |
| describe('Bytes access', () => { |
| const simpleByteString = ByteString.fromArrayBuffer(createArrayBuffer(1)); |
| |
| it('returns default value for empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getBytesWithDefault(1)).toEqual(ByteString.EMPTY); |
| }); |
| |
| it('returns the default from parameter', () => { |
| const defaultByteString = ByteString.fromArrayBuffer(createArrayBuffer(1)); |
| const returnValue = ByteString.fromArrayBuffer(createArrayBuffer(1)); |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getBytesWithDefault(1, defaultByteString)) |
| .toEqual(returnValue); |
| }); |
| |
| it('decodes value from wire', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x01)); |
| expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); |
| }); |
| |
| it('decodes value from wire with multple values being present', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0x0A, 0x01, 0x00, 0x0A, 0x01, 0x01)); |
| expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); |
| }); |
| |
| it('fails when getting value with other wire types', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( |
| 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01)); |
| if (CHECK_CRITICAL_TYPE) { |
| expect(() => { |
| accessor.getBytesWithDefault(1); |
| }).toThrowError('Expected wire type: 2 but found: 1'); |
| } else { |
| // Note in unchecked mode we produce invalid output for invalid inputs. |
| // This test just documents our behavior in those cases. |
| // These values might change at any point and are not considered |
| // what the implementation should be doing here. |
| const arrayBuffer = createArrayBuffer(1); |
| expect(accessor.getBytesWithDefault(1)) |
| .toEqual(ByteString.fromArrayBuffer(arrayBuffer)); |
| } |
| }); |
| |
| it('throws in getter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect( |
| () => LazyAccessor.createEmpty().getBytesWithDefault( |
| -1, simpleByteString)) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| expect( |
| LazyAccessor.createEmpty().getBytesWithDefault(-1, simpleByteString)) |
| .toEqual(simpleByteString); |
| } |
| }); |
| |
| it('returns the value from setter', () => { |
| const bytes = createArrayBuffer(0x0A, 0x01, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.setBytes(1, simpleByteString); |
| expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); |
| }); |
| |
| it('encode the value from setter', () => { |
| const bytes = createArrayBuffer(0x0A, 0x01, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const newBytes = createArrayBuffer(0x0A, 0x01, 0x01); |
| accessor.setBytes(1, simpleByteString); |
| expect(accessor.serialize()).toEqual(newBytes); |
| }); |
| |
| it('returns value from cache', () => { |
| const bytes = createArrayBuffer(0x0A, 0x01, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); |
| // Make sure the value is cached. |
| bytes[2] = 0x00; |
| expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); |
| }); |
| |
| it('throws in setter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().setBytes(-1, simpleByteString)) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setBytes(-1, simpleByteString); |
| expect(accessor.getBytesWithDefault(-1)).toEqual(simpleByteString); |
| } |
| }); |
| |
| it('throws in setter for invalid value', () => { |
| if (CHECK_CRITICAL_TYPE) { |
| expect( |
| () => LazyAccessor.createEmpty().setBytes( |
| 1, /** @type {!ByteString} */ (/** @type {*} */ (null)))) |
| .toThrow(); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setBytes( |
| 1, /** @type {!ByteString} */ (/** @type {*} */ (null))); |
| expect(accessor.getBytesWithDefault(1)).toEqual(null); |
| } |
| }); |
| }); |
| |
| describe('Fixed32 access', () => { |
| it('returns default value for empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getFixed32WithDefault(1)).toEqual(0); |
| }); |
| |
| it('returns the default from parameter', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getFixed32WithDefault(1, 2)).toEqual(2); |
| }); |
| |
| it('decodes value from wire', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00)); |
| expect(accessor.getFixed32WithDefault(1)).toEqual(1); |
| }); |
| |
| it('decodes value from wire with multple values being present', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( |
| 0x0D, 0x01, 0x00, 0x80, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00)); |
| expect(accessor.getFixed32WithDefault(1)).toEqual(2); |
| }); |
| |
| it('fails when getting value with other wire types', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); |
| if (CHECK_CRITICAL_TYPE) { |
| expect(() => { |
| accessor.getFixed32WithDefault(1); |
| }).toThrowError('Expected wire type: 5 but found: 0'); |
| } else { |
| // Note in unchecked mode we produce invalid output for invalid inputs. |
| // This test just documents our behavior in those cases. |
| // These values might change at any point and are not considered |
| // what the implementation should be doing here. |
| expect(accessor.getFixed32WithDefault(1)).toEqual(8421504); |
| } |
| }); |
| |
| it('throws in getter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().getFixed32WithDefault(-1, 1)) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| expect(LazyAccessor.createEmpty().getFixed32WithDefault(-1, 1)) |
| .toEqual(1); |
| } |
| }); |
| |
| it('returns the value from setter', () => { |
| const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.setFixed32(1, 2); |
| expect(accessor.getFixed32WithDefault(1)).toEqual(2); |
| }); |
| |
| it('encode the value from setter', () => { |
| const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const newBytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00); |
| accessor.setFixed32(1, 0); |
| expect(accessor.serialize()).toEqual(newBytes); |
| }); |
| |
| it('returns value from cache', () => { |
| const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getFixed32WithDefault(1)).toBe(1); |
| // Make sure the value is cached. |
| bytes[2] = 0x00; |
| expect(accessor.getFixed32WithDefault(1)).toBe(1); |
| }); |
| |
| it('throws in setter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().setFixed32(-1, 1)) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setFixed32(-1, 1); |
| expect(accessor.getFixed32WithDefault(-1)).toEqual(1); |
| } |
| }); |
| |
| it('throws in setter for invalid value', () => { |
| if (CHECK_CRITICAL_TYPE) { |
| expect( |
| () => LazyAccessor.createEmpty().setFixed32( |
| 1, /** @type {number} */ (/** @type {*} */ (null)))) |
| .toThrow(); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setFixed32(1, /** @type {number} */ (/** @type {*} */ (null))); |
| expect(accessor.getFixed32WithDefault(1)).toEqual(null); |
| } |
| }); |
| }); |
| |
| describe('Fixed64 access', () => { |
| it('returns default value for empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(0)); |
| }); |
| |
| it('returns the default from parameter', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getFixed64WithDefault(1, Int64.fromInt(2))) |
| .toEqual(Int64.fromInt(2)); |
| }); |
| |
| it('decodes value from wire', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( |
| 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); |
| expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(1)); |
| }); |
| |
| it('decodes value from wire with multple values being present', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( |
| 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); |
| expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(2)); |
| }); |
| |
| if (CHECK_CRITICAL_STATE) { |
| it('fails when getting value with other wire types', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); |
| expect(() => { |
| accessor.getFixed64WithDefault(1); |
| }).toThrow(); |
| }); |
| } |
| |
| it('throws in getter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect( |
| () => LazyAccessor.createEmpty().getFixed64WithDefault( |
| -1, Int64.fromInt(1))) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| expect(LazyAccessor.createEmpty().getFixed64WithDefault( |
| -1, Int64.fromInt(1))) |
| .toEqual(Int64.fromInt(1)); |
| } |
| }); |
| |
| it('returns the value from setter', () => { |
| const bytes = |
| createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.setFixed64(1, Int64.fromInt(2)); |
| expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(2)); |
| }); |
| |
| it('encode the value from setter', () => { |
| const bytes = |
| createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const newBytes = |
| createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); |
| accessor.setFixed64(1, Int64.fromInt(0)); |
| expect(accessor.serialize()).toEqual(newBytes); |
| }); |
| |
| it('returns value from cache', () => { |
| const bytes = |
| createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(1)); |
| // Make sure the value is cached. |
| bytes[2] = 0x00; |
| expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(1)); |
| }); |
| |
| it('throws in setter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().setFixed64(-1, Int64.fromInt(1))) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setFixed64(-1, Int64.fromInt(1)); |
| expect(accessor.getFixed64WithDefault(-1)).toEqual(Int64.fromInt(1)); |
| } |
| }); |
| |
| it('throws in setter for invalid value', () => { |
| if (CHECK_CRITICAL_TYPE) { |
| expect( |
| () => LazyAccessor.createEmpty().setSfixed64( |
| 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) |
| .toThrow(); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setFixed64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); |
| expect(accessor.getFixed64WithDefault(1)).toEqual(null); |
| } |
| }); |
| }); |
| |
| describe('Float access', () => { |
| it('returns default value for empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getFloatWithDefault(1)).toEqual(0); |
| }); |
| |
| it('returns the default from parameter', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getFloatWithDefault(1, 2)).toEqual(2); |
| }); |
| |
| it('decodes value from wire', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0x0D, 0x00, 0x00, 0x80, 0x3F)); |
| expect(accessor.getFloatWithDefault(1)).toEqual(1); |
| }); |
| |
| it('decodes value from wire with multple values being present', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( |
| 0x0D, 0x00, 0x00, 0x80, 0x3F, 0x0D, 0x00, 0x00, 0x80, 0xBF)); |
| expect(accessor.getFloatWithDefault(1)).toEqual(-1); |
| }); |
| |
| if (CHECK_CRITICAL_STATE) { |
| it('fails when getting float value with other wire types', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( |
| 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F)); |
| expect(() => { |
| accessor.getFloatWithDefault(1); |
| }).toThrow(); |
| }); |
| } |
| |
| |
| it('throws in getter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().getFloatWithDefault(-1, 1)) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| expect(LazyAccessor.createEmpty().getFloatWithDefault(-1, 1)).toEqual(1); |
| } |
| }); |
| |
| it('returns the value from setter', () => { |
| const bytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x80, 0x3F); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.setFloat(1, 1.6); |
| expect(accessor.getFloatWithDefault(1)).toEqual(Math.fround(1.6)); |
| }); |
| |
| it('encode the value from setter', () => { |
| const bytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x80, 0x3F); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const newBytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00); |
| accessor.setFloat(1, 0); |
| expect(accessor.serialize()).toEqual(newBytes); |
| }); |
| |
| it('returns float value from cache', () => { |
| const bytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x80, 0x3F); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getFloatWithDefault(1)).toBe(1); |
| // Make sure the value is cached. |
| bytes[2] = 0x00; |
| expect(accessor.getFloatWithDefault(1)).toBe(1); |
| }); |
| |
| it('throws in setter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().setFloat(-1, 1)) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setFloat(-1, 1); |
| expect(accessor.getFloatWithDefault(-1)).toEqual(1); |
| } |
| }); |
| |
| it('throws in setter for invalid value', () => { |
| if (CHECK_CRITICAL_TYPE) { |
| expect( |
| () => LazyAccessor.createEmpty().setFloat( |
| 1, /** @type {number} */ (/** @type {*} */ (null)))) |
| .toThrow(); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setFloat(1, /** @type {number} */ (/** @type {*} */ (null))); |
| expect(accessor.getFloatWithDefault(1)).toEqual(0); |
| } |
| }); |
| |
| it('throws in setter for value outside of float32 precision', () => { |
| if (CHECK_CRITICAL_TYPE) { |
| expect(() => LazyAccessor.createEmpty().setFloat(1, Number.MAX_VALUE)) |
| .toThrow(); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setFloat(1, Number.MAX_VALUE); |
| expect(accessor.getFloatWithDefault(1)).toEqual(Infinity); |
| } |
| }); |
| }); |
| |
| describe('Int32 access', () => { |
| it('returns default value for empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getInt32WithDefault(1)).toEqual(0); |
| }); |
| |
| it('returns the default from parameter', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getInt32WithDefault(1, 2)).toEqual(2); |
| }); |
| |
| it('decodes value from wire', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); |
| expect(accessor.getInt32WithDefault(1)).toEqual(1); |
| }); |
| |
| it('decodes value from wire with multple values being present', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); |
| expect(accessor.getInt32WithDefault(1)).toEqual(2); |
| }); |
| |
| it('fails when getting value with other wire types', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); |
| if (CHECK_CRITICAL_TYPE) { |
| expect(() => { |
| accessor.getInt32WithDefault(1); |
| }).toThrowError('Expected wire type: 0 but found: 5'); |
| } else { |
| // Note in unchecked mode we produce invalid output for invalid inputs. |
| // This test just documents our behavior in those cases. |
| // These values might change at any point and are not considered |
| // what the implementation should be doing here. |
| expect(accessor.getInt32WithDefault(1)).toEqual(0); |
| } |
| }); |
| |
| it('throws in getter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().getInt32WithDefault(-1, 1)) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| expect(LazyAccessor.createEmpty().getInt32WithDefault(-1, 1)).toEqual(1); |
| } |
| }); |
| |
| it('returns the value from setter', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.setInt32(1, 2); |
| expect(accessor.getInt32WithDefault(1)).toEqual(2); |
| }); |
| |
| it('encode the value from setter', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const newBytes = createArrayBuffer(0x08, 0x00); |
| accessor.setInt32(1, 0); |
| expect(accessor.serialize()).toEqual(newBytes); |
| }); |
| |
| it('returns value from cache', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getInt32WithDefault(1)).toBe(1); |
| // Make sure the value is cached. |
| bytes[2] = 0x00; |
| expect(accessor.getInt32WithDefault(1)).toBe(1); |
| }); |
| |
| it('throws in setter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().setInt32(-1, 1)) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setInt32(-1, 1); |
| expect(accessor.getInt32WithDefault(-1)).toEqual(1); |
| } |
| }); |
| |
| it('throws in setter for invalid value', () => { |
| if (CHECK_CRITICAL_TYPE) { |
| expect( |
| () => LazyAccessor.createEmpty().setInt32( |
| 1, /** @type {number} */ (/** @type {*} */ (null)))) |
| .toThrow(); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setInt32(1, /** @type {number} */ (/** @type {*} */ (null))); |
| expect(accessor.getInt32WithDefault(1)).toEqual(null); |
| } |
| }); |
| }); |
| |
| describe('Int64 access', () => { |
| it('returns default value for empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(0)); |
| }); |
| |
| it('returns the default from parameter', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getInt64WithDefault(1, Int64.fromInt(2))) |
| .toEqual(Int64.fromInt(2)); |
| }); |
| |
| it('decodes value from wire', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); |
| expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(1)); |
| }); |
| |
| it('decodes value from wire with multple values being present', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); |
| expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(2)); |
| }); |
| |
| it('fails when getting value with other wire types', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); |
| if (CHECK_CRITICAL_TYPE) { |
| expect(() => { |
| accessor.getInt64WithDefault(1); |
| }).toThrowError('Expected wire type: 0 but found: 5'); |
| } else { |
| // Note in unchecked mode we produce invalid output for invalid inputs. |
| // This test just documents our behavior in those cases. |
| // These values might change at any point and are not considered |
| // what the implementation should be doing here. |
| expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(0)); |
| } |
| }); |
| |
| it('throws in getter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect( |
| () => LazyAccessor.createEmpty().getInt64WithDefault( |
| -1, Int64.fromInt(1))) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| expect( |
| LazyAccessor.createEmpty().getInt64WithDefault(-1, Int64.fromInt(1))) |
| .toEqual(Int64.fromInt(1)); |
| } |
| }); |
| |
| it('returns the value from setter', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.setInt64(1, Int64.fromInt(2)); |
| expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(2)); |
| }); |
| |
| it('encode the value from setter', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const newBytes = createArrayBuffer(0x08, 0x00); |
| accessor.setInt64(1, Int64.fromInt(0)); |
| expect(accessor.serialize()).toEqual(newBytes); |
| }); |
| |
| it('returns value from cache', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(1)); |
| // Make sure the value is cached. |
| bytes[2] = 0x00; |
| expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(1)); |
| }); |
| |
| it('throws in setter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().setInt64(-1, Int64.fromInt(1))) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setInt64(-1, Int64.fromInt(1)); |
| expect(accessor.getInt64WithDefault(-1)).toEqual(Int64.fromInt(1)); |
| } |
| }); |
| |
| it('throws in setter for invalid value', () => { |
| if (CHECK_CRITICAL_TYPE) { |
| expect( |
| () => LazyAccessor.createEmpty().setInt64( |
| 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) |
| .toThrow(); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setInt64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); |
| expect(accessor.getInt64WithDefault(1)).toEqual(null); |
| } |
| }); |
| }); |
| |
| describe('Sfixed32 access', () => { |
| it('returns default value for empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getSfixed32WithDefault(1)).toEqual(0); |
| }); |
| |
| it('returns the default from parameter', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getSfixed32WithDefault(1, 2)).toEqual(2); |
| }); |
| |
| it('decodes value from wire', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00)); |
| expect(accessor.getSfixed32WithDefault(1)).toEqual(1); |
| }); |
| |
| it('decodes value from wire with multple values being present', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( |
| 0x0D, 0x01, 0x00, 0x80, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00)); |
| expect(accessor.getSfixed32WithDefault(1)).toEqual(2); |
| }); |
| |
| it('fails when getting value with other wire types', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); |
| if (CHECK_CRITICAL_TYPE) { |
| expect(() => { |
| accessor.getSfixed32WithDefault(1); |
| }).toThrowError('Expected wire type: 5 but found: 0'); |
| } else { |
| // Note in unchecked mode we produce invalid output for invalid inputs. |
| // This test just documents our behavior in those cases. |
| // These values might change at any point and are not considered |
| // what the implementation should be doing here. |
| expect(accessor.getSfixed32WithDefault(1)).toEqual(8421504); |
| } |
| }); |
| |
| it('throws in getter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().getSfixed32WithDefault(-1, 1)) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| expect(LazyAccessor.createEmpty().getSfixed32WithDefault(-1, 1)) |
| .toEqual(1); |
| } |
| }); |
| |
| it('returns the value from setter', () => { |
| const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.setSfixed32(1, 2); |
| expect(accessor.getSfixed32WithDefault(1)).toEqual(2); |
| }); |
| |
| it('encode the value from setter', () => { |
| const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const newBytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00); |
| accessor.setSfixed32(1, 0); |
| expect(accessor.serialize()).toEqual(newBytes); |
| }); |
| |
| it('returns value from cache', () => { |
| const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getSfixed32WithDefault(1)).toBe(1); |
| // Make sure the value is cached. |
| bytes[2] = 0x00; |
| expect(accessor.getSfixed32WithDefault(1)).toBe(1); |
| }); |
| |
| it('throws in setter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().setSfixed32(-1, 1)) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setSfixed32(-1, 1); |
| expect(accessor.getSfixed32WithDefault(-1)).toEqual(1); |
| } |
| }); |
| |
| it('throws in setter for invalid value', () => { |
| if (CHECK_CRITICAL_TYPE) { |
| expect( |
| () => LazyAccessor.createEmpty().setSfixed32( |
| 1, /** @type {number} */ (/** @type {*} */ (null)))) |
| .toThrow(); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setSfixed32(1, /** @type {number} */ (/** @type {*} */ (null))); |
| expect(accessor.getSfixed32WithDefault(1)).toEqual(null); |
| } |
| }); |
| }); |
| |
| describe('Sfixed64 access', () => { |
| it('returns default value for empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(0)); |
| }); |
| |
| it('returns the default from parameter', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getSfixed64WithDefault(1, Int64.fromInt(2))) |
| .toEqual(Int64.fromInt(2)); |
| }); |
| |
| it('decodes value from wire', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( |
| 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); |
| expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(1)); |
| }); |
| |
| it('decodes value from wire with multple values being present', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( |
| 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); |
| expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(2)); |
| }); |
| |
| if (CHECK_CRITICAL_STATE) { |
| it('fails when getting value with other wire types', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); |
| expect(() => { |
| accessor.getSfixed64WithDefault(1); |
| }).toThrow(); |
| }); |
| } |
| |
| it('throws in getter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect( |
| () => LazyAccessor.createEmpty().getSfixed64WithDefault( |
| -1, Int64.fromInt(1))) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| expect(LazyAccessor.createEmpty().getSfixed64WithDefault( |
| -1, Int64.fromInt(1))) |
| .toEqual(Int64.fromInt(1)); |
| } |
| }); |
| |
| it('returns the value from setter', () => { |
| const bytes = |
| createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.setSfixed64(1, Int64.fromInt(2)); |
| expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(2)); |
| }); |
| |
| it('encode the value from setter', () => { |
| const bytes = |
| createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const newBytes = |
| createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); |
| accessor.setSfixed64(1, Int64.fromInt(0)); |
| expect(accessor.serialize()).toEqual(newBytes); |
| }); |
| |
| it('returns value from cache', () => { |
| const bytes = |
| createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(1)); |
| // Make sure the value is cached. |
| bytes[2] = 0x00; |
| expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(1)); |
| }); |
| |
| it('throws in setter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().setSfixed64(-1, Int64.fromInt(1))) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setSfixed64(-1, Int64.fromInt(1)); |
| expect(accessor.getSfixed64WithDefault(-1)).toEqual(Int64.fromInt(1)); |
| } |
| }); |
| |
| it('throws in setter for invalid value', () => { |
| if (CHECK_CRITICAL_TYPE) { |
| expect( |
| () => LazyAccessor.createEmpty().setSfixed64( |
| 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) |
| .toThrow(); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setSfixed64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); |
| expect(accessor.getSfixed64WithDefault(1)).toEqual(null); |
| } |
| }); |
| }); |
| |
| describe('Sint32 access', () => { |
| it('returns default value for empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getSint32WithDefault(1)).toEqual(0); |
| }); |
| |
| it('returns the default from parameter', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getSint32WithDefault(1, 2)).toEqual(2); |
| }); |
| |
| it('decodes value from wire', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x02)); |
| expect(accessor.getSint32WithDefault(1)).toEqual(1); |
| }); |
| |
| it('decodes value from wire with multple values being present', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x03, 0x08, 0x02)); |
| expect(accessor.getSint32WithDefault(1)).toEqual(1); |
| }); |
| |
| it('fails when getting value with other wire types', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); |
| if (CHECK_CRITICAL_TYPE) { |
| expect(() => { |
| accessor.getSint32WithDefault(1); |
| }).toThrowError('Expected wire type: 0 but found: 5'); |
| } else { |
| // Note in unchecked mode we produce invalid output for invalid inputs. |
| // This test just documents our behavior in those cases. |
| // These values might change at any point and are not considered |
| // what the implementation should be doing here. |
| expect(accessor.getSint32WithDefault(1)).toEqual(0); |
| } |
| }); |
| |
| it('throws in getter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().getSint32WithDefault(-1, 1)) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| expect(LazyAccessor.createEmpty().getSint32WithDefault(-1, 1)).toEqual(1); |
| } |
| }); |
| |
| it('returns the value from setter', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.setSint32(1, 2); |
| expect(accessor.getSint32WithDefault(1)).toEqual(2); |
| }); |
| |
| it('encode the value from setter', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const newBytes = createArrayBuffer(0x08, 0x00); |
| accessor.setSint32(1, 0); |
| expect(accessor.serialize()).toEqual(newBytes); |
| }); |
| |
| it('returns value from cache', () => { |
| const bytes = createArrayBuffer(0x08, 0x02); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getSint32WithDefault(1)).toBe(1); |
| // Make sure the value is cached. |
| bytes[2] = 0x00; |
| expect(accessor.getSint32WithDefault(1)).toBe(1); |
| }); |
| |
| it('throws in setter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().setSint32(-1, 1)) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setSint32(-1, 1); |
| expect(accessor.getSint32WithDefault(-1)).toEqual(1); |
| } |
| }); |
| |
| it('throws in setter for invalid value', () => { |
| if (CHECK_CRITICAL_TYPE) { |
| expect( |
| () => LazyAccessor.createEmpty().setSint32( |
| 1, /** @type {number} */ (/** @type {*} */ (null)))) |
| .toThrow(); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setSint32(1, /** @type {number} */ (/** @type {*} */ (null))); |
| expect(accessor.getSint32WithDefault(1)).toEqual(null); |
| } |
| }); |
| }); |
| |
| describe('SInt64 access', () => { |
| it('returns default value for empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(0)); |
| }); |
| |
| it('returns the default from parameter', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getSint64WithDefault(1, Int64.fromInt(2))) |
| .toEqual(Int64.fromInt(2)); |
| }); |
| |
| it('decodes value from wire', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x02)); |
| expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1)); |
| }); |
| |
| it('decodes value from wire with multple values being present', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); |
| expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1)); |
| }); |
| |
| it('fails when getting value with other wire types', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); |
| if (CHECK_CRITICAL_TYPE) { |
| expect(() => { |
| accessor.getSint64WithDefault(1); |
| }).toThrowError('Expected wire type: 0 but found: 5'); |
| } else { |
| // Note in unchecked mode we produce invalid output for invalid inputs. |
| // This test just documents our behavior in those cases. |
| // These values might change at any point and are not considered |
| // what the implementation should be doing here. |
| expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(0)); |
| } |
| }); |
| |
| it('throws in getter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect( |
| () => LazyAccessor.createEmpty().getSint64WithDefault( |
| -1, Int64.fromInt(1))) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| expect( |
| LazyAccessor.createEmpty().getSint64WithDefault(-1, Int64.fromInt(1))) |
| .toEqual(Int64.fromInt(1)); |
| } |
| }); |
| |
| it('returns the value from setter', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.setSint64(1, Int64.fromInt(2)); |
| expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(2)); |
| }); |
| |
| it('encode the value from setter', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const newBytes = createArrayBuffer(0x08, 0x00); |
| accessor.setSint64(1, Int64.fromInt(0)); |
| expect(accessor.serialize()).toEqual(newBytes); |
| }); |
| |
| it('returns value from cache', () => { |
| const bytes = createArrayBuffer(0x08, 0x02); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1)); |
| // Make sure the value is cached. |
| bytes[1] = 0x00; |
| expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1)); |
| }); |
| |
| it('throws in setter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().setSint64(-1, Int64.fromInt(1))) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setInt64(-1, Int64.fromInt(1)); |
| expect(accessor.getSint64WithDefault(-1)).toEqual(Int64.fromInt(1)); |
| } |
| }); |
| |
| it('throws in setter for invalid value', () => { |
| if (CHECK_CRITICAL_TYPE) { |
| expect( |
| () => LazyAccessor.createEmpty().setSint64( |
| 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) |
| .toThrow(); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setSint64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); |
| expect(accessor.getSint64WithDefault(1)).toEqual(null); |
| } |
| }); |
| }); |
| |
| describe('String access', () => { |
| it('returns empty string for the empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getStringWithDefault(1)).toEqual(''); |
| }); |
| |
| it('returns the default for the empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getStringWithDefault(1, 'bar')).toEqual('bar'); |
| }); |
| |
| it('decodes value from wire', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x61)); |
| expect(accessor.getStringWithDefault(1)).toEqual('a'); |
| }); |
| |
| it('decodes value from wire with multple values being present', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0x0A, 0x01, 0x60, 0x0A, 0x01, 0x61)); |
| expect(accessor.getStringWithDefault(1)).toEqual('a'); |
| }); |
| |
| if (CHECK_CRITICAL_STATE) { |
| it('fails when getting string value with other wire types', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0x08, 0x02, 0x08, 0x08)); |
| expect(() => { |
| accessor.getStringWithDefault(1); |
| }).toThrow(); |
| }); |
| } |
| |
| |
| it('throws in getter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().getStringWithDefault(-1, 'a')) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| expect(LazyAccessor.createEmpty().getStringWithDefault(-1, 'a')) |
| .toEqual('a'); |
| } |
| }); |
| |
| it('returns the value from setter', () => { |
| const bytes = createArrayBuffer(0x0A, 0x01, 0x61); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.setString(1, 'b'); |
| expect(accessor.getStringWithDefault(1)).toEqual('b'); |
| }); |
| |
| it('encode the value from setter', () => { |
| const bytes = createArrayBuffer(0x0A, 0x01, 0x61); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const newBytes = createArrayBuffer(0x0A, 0x01, 0x62); |
| accessor.setString(1, 'b'); |
| expect(accessor.serialize()).toEqual(newBytes); |
| }); |
| |
| it('returns string value from cache', () => { |
| const bytes = createArrayBuffer(0x0A, 0x01, 0x61); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getStringWithDefault(1)).toBe('a'); |
| // Make sure the value is cached. |
| bytes[2] = 0x00; |
| expect(accessor.getStringWithDefault(1)).toBe('a'); |
| }); |
| |
| it('throws in setter for invalid fieldNumber', () => { |
| if (CHECK_TYPE) { |
| expect(() => LazyAccessor.createEmpty().setString(-1, 'a')) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setString(-1, 'a'); |
| expect(accessor.getStringWithDefault(-1)).toEqual('a'); |
| } |
| }); |
| |
| it('throws in setter for invalid value', () => { |
| if (CHECK_CRITICAL_TYPE) { |
| expect( |
| () => LazyAccessor.createEmpty().setString( |
| 1, /** @type {string} */ (/** @type {*} */ (null)))) |
| .toThrowError('Must be string, but got: null'); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setString(1, /** @type {string} */ (/** @type {*} */ (null))); |
| expect(accessor.getStringWithDefault(1)).toEqual(null); |
| } |
| }); |
| }); |
| |
| describe('Uint32 access', () => { |
| it('returns default value for empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getUint32WithDefault(1)).toEqual(0); |
| }); |
| |
| it('returns the default from parameter', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getUint32WithDefault(1, 2)).toEqual(2); |
| }); |
| |
| it('decodes value from wire', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); |
| expect(accessor.getUint32WithDefault(1)).toEqual(1); |
| }); |
| |
| it('decodes value from wire with multple values being present', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); |
| expect(accessor.getUint32WithDefault(1)).toEqual(2); |
| }); |
| |
| it('fails when getting value with other wire types', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); |
| if (CHECK_CRITICAL_TYPE) { |
| expect(() => { |
| accessor.getUint32WithDefault(1); |
| }).toThrowError('Expected wire type: 0 but found: 5'); |
| } else { |
| // Note in unchecked mode we produce invalid output for invalid inputs. |
| // This test just documents our behavior in those cases. |
| // These values might change at any point and are not considered |
| // what the implementation should be doing here. |
| expect(accessor.getUint32WithDefault(1)).toEqual(0); |
| } |
| }); |
| |
| it('throws in getter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().getUint32WithDefault(-1, 1)) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| expect(LazyAccessor.createEmpty().getUint32WithDefault(-1, 1)).toEqual(1); |
| } |
| }); |
| |
| it('returns the value from setter', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.setUint32(1, 2); |
| expect(accessor.getUint32WithDefault(1)).toEqual(2); |
| }); |
| |
| it('encode the value from setter', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const newBytes = createArrayBuffer(0x08, 0x00); |
| accessor.setUint32(1, 0); |
| expect(accessor.serialize()).toEqual(newBytes); |
| }); |
| |
| it('returns value from cache', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getUint32WithDefault(1)).toBe(1); |
| // Make sure the value is cached. |
| bytes[2] = 0x00; |
| expect(accessor.getUint32WithDefault(1)).toBe(1); |
| }); |
| |
| it('throws in setter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().setInt32(-1, 1)) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setUint32(-1, 1); |
| expect(accessor.getUint32WithDefault(-1)).toEqual(1); |
| } |
| }); |
| |
| it('throws in setter for invalid value', () => { |
| if (CHECK_CRITICAL_TYPE) { |
| expect( |
| () => LazyAccessor.createEmpty().setUint32( |
| 1, /** @type {number} */ (/** @type {*} */ (null)))) |
| .toThrow(); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setUint32(1, /** @type {number} */ (/** @type {*} */ (null))); |
| expect(accessor.getUint32WithDefault(1)).toEqual(null); |
| } |
| }); |
| }); |
| |
| describe('Uint64 access', () => { |
| it('returns default value for empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(0)); |
| }); |
| |
| it('returns the default from parameter', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getUint64WithDefault(1, Int64.fromInt(2))) |
| .toEqual(Int64.fromInt(2)); |
| }); |
| |
| it('decodes value from wire', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); |
| expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(1)); |
| }); |
| |
| it('decodes value from wire with multple values being present', () => { |
| const accessor = |
| LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); |
| expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(2)); |
| }); |
| |
| it('fails when getting value with other wire types', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); |
| if (CHECK_CRITICAL_TYPE) { |
| expect(() => { |
| accessor.getUint64WithDefault(1); |
| }).toThrowError('Expected wire type: 0 but found: 5'); |
| } else { |
| // Note in unchecked mode we produce invalid output for invalid inputs. |
| // This test just documents our behavior in those cases. |
| // These values might change at any point and are not considered |
| // what the implementation should be doing here. |
| expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(0)); |
| } |
| }); |
| |
| it('throws in getter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect( |
| () => LazyAccessor.createEmpty().getUint64WithDefault( |
| -1, Int64.fromInt(1))) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| expect( |
| LazyAccessor.createEmpty().getUint64WithDefault(-1, Int64.fromInt(1))) |
| .toEqual(Int64.fromInt(1)); |
| } |
| }); |
| |
| it('returns the value from setter', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.setUint64(1, Int64.fromInt(2)); |
| expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(2)); |
| }); |
| |
| it('encode the value from setter', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const newBytes = createArrayBuffer(0x08, 0x00); |
| accessor.setUint64(1, Int64.fromInt(0)); |
| expect(accessor.serialize()).toEqual(newBytes); |
| }); |
| |
| it('returns value from cache', () => { |
| const bytes = createArrayBuffer(0x08, 0x01); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(1)); |
| // Make sure the value is cached. |
| bytes[2] = 0x00; |
| expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(1)); |
| }); |
| |
| it('throws in setter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().setUint64(-1, Int64.fromInt(1))) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setUint64(-1, Int64.fromInt(1)); |
| expect(accessor.getUint64WithDefault(-1)).toEqual(Int64.fromInt(1)); |
| } |
| }); |
| |
| it('throws in setter for invalid value', () => { |
| if (CHECK_CRITICAL_TYPE) { |
| expect( |
| () => LazyAccessor.createEmpty().setUint64( |
| 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) |
| .toThrow(); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setUint64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); |
| expect(accessor.getUint64WithDefault(1)).toEqual(null); |
| } |
| }); |
| }); |
| |
| describe('Double access', () => { |
| it('returns default value for empty input', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getDoubleWithDefault(1)).toEqual(0); |
| }); |
| |
| it('returns the default from parameter', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); |
| expect(accessor.getDoubleWithDefault(1, 2)).toEqual(2); |
| }); |
| |
| it('decodes value from wire', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( |
| 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F)); |
| expect(accessor.getDoubleWithDefault(1)).toEqual(1); |
| }); |
| |
| |
| it('decodes value from wire with multple values being present', () => { |
| const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( |
| 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x09, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0xF0, 0xBF)); |
| expect(accessor.getDoubleWithDefault(1)).toEqual(-1); |
| }); |
| |
| if (CHECK_CRITICAL_STATE) { |
| it('fails when getting double value with other wire types', () => { |
| const accessor = LazyAccessor.fromArrayBuffer( |
| createArrayBuffer(0x0D, 0x00, 0x00, 0xF0, 0x3F)); |
| expect(() => { |
| accessor.getDoubleWithDefault(1); |
| }).toThrow(); |
| }); |
| } |
| |
| |
| it('throws in getter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().getDoubleWithDefault(-1, 1)) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| expect(LazyAccessor.createEmpty().getDoubleWithDefault(-1, 1)).toEqual(1); |
| } |
| }); |
| |
| it('returns the value from setter', () => { |
| const bytes = |
| createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| accessor.setDouble(1, 2); |
| expect(accessor.getDoubleWithDefault(1)).toEqual(2); |
| }); |
| |
| it('encode the value from setter', () => { |
| const bytes = |
| createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| const newBytes = |
| createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); |
| accessor.setDouble(1, 0); |
| expect(accessor.serialize()).toEqual(newBytes); |
| }); |
| |
| it('returns string value from cache', () => { |
| const bytes = |
| createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F); |
| const accessor = LazyAccessor.fromArrayBuffer(bytes); |
| expect(accessor.getDoubleWithDefault(1)).toBe(1); |
| // Make sure the value is cached. |
| bytes[2] = 0x00; |
| expect(accessor.getDoubleWithDefault(1)).toBe(1); |
| }); |
| |
| it('throws in setter for invalid fieldNumber', () => { |
| if (CHECK_BOUNDS) { |
| expect(() => LazyAccessor.createEmpty().setDouble(-1, 1)) |
| .toThrowError('Field number is out of range: -1'); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setDouble(-1, 1); |
| expect(accessor.getDoubleWithDefault(-1)).toEqual(1); |
| } |
| }); |
| |
| it('throws in setter for invalid value', () => { |
| if (CHECK_CRITICAL_TYPE) { |
| expect( |
| () => LazyAccessor.createEmpty().setDouble( |
| 1, /** @type {number} */ (/** @type {*} */ (null)))) |
| .toThrowError('Must be a number, but got: null'); |
| } else { |
| const accessor = LazyAccessor.createEmpty(); |
| accessor.setDouble(1, /** @type {number} */ (/** @type {*} */ (null))); |
| expect(accessor.getDoubleWithDefault(1)).toEqual(null); |
| } |
| }); |
| }); |