1ffe3c632Sopenharmony_ci/** 2ffe3c632Sopenharmony_ci * @fileoverview Tests for indexer.js. 3ffe3c632Sopenharmony_ci */ 4ffe3c632Sopenharmony_cigoog.module('protobuf.binary.IndexerTest'); 5ffe3c632Sopenharmony_ci 6ffe3c632Sopenharmony_cigoog.setTestOnly(); 7ffe3c632Sopenharmony_ci 8ffe3c632Sopenharmony_ci// Note to the reader: 9ffe3c632Sopenharmony_ci// Since the index behavior changes with the checking level some of the tests 10ffe3c632Sopenharmony_ci// in this file have to know which checking level is enabled to make correct 11ffe3c632Sopenharmony_ci// assertions. 12ffe3c632Sopenharmony_ci// Test are run in all checking levels. 13ffe3c632Sopenharmony_ciconst BinaryStorage = goog.require('protobuf.runtime.BinaryStorage'); 14ffe3c632Sopenharmony_ciconst BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); 15ffe3c632Sopenharmony_ciconst WireType = goog.require('protobuf.binary.WireType'); 16ffe3c632Sopenharmony_ciconst {CHECK_CRITICAL_STATE} = goog.require('protobuf.internal.checks'); 17ffe3c632Sopenharmony_ciconst {Field, IndexEntry} = goog.require('protobuf.binary.field'); 18ffe3c632Sopenharmony_ciconst {buildIndex} = goog.require('protobuf.binary.indexer'); 19ffe3c632Sopenharmony_ciconst {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); 20ffe3c632Sopenharmony_ci 21ffe3c632Sopenharmony_ci/** 22ffe3c632Sopenharmony_ci * Returns the number of fields stored. 23ffe3c632Sopenharmony_ci * 24ffe3c632Sopenharmony_ci * @param {!BinaryStorage} storage 25ffe3c632Sopenharmony_ci * @return {number} 26ffe3c632Sopenharmony_ci */ 27ffe3c632Sopenharmony_cifunction getStorageSize(storage) { 28ffe3c632Sopenharmony_ci let size = 0; 29ffe3c632Sopenharmony_ci storage.forEach(() => void size++); 30ffe3c632Sopenharmony_ci return size; 31ffe3c632Sopenharmony_ci} 32ffe3c632Sopenharmony_ci 33ffe3c632Sopenharmony_ci/** 34ffe3c632Sopenharmony_ci * @type {number} 35ffe3c632Sopenharmony_ci */ 36ffe3c632Sopenharmony_ciconst PIVOT = 1; 37ffe3c632Sopenharmony_ci 38ffe3c632Sopenharmony_ci/** 39ffe3c632Sopenharmony_ci * Asserts a single IndexEntry at a given field number. 40ffe3c632Sopenharmony_ci * @param {!BinaryStorage} storage 41ffe3c632Sopenharmony_ci * @param {number} fieldNumber 42ffe3c632Sopenharmony_ci * @param {...!IndexEntry} expectedEntries 43ffe3c632Sopenharmony_ci */ 44ffe3c632Sopenharmony_cifunction assertStorageEntries(storage, fieldNumber, ...expectedEntries) { 45ffe3c632Sopenharmony_ci expect(getStorageSize(storage)).toBe(1); 46ffe3c632Sopenharmony_ci 47ffe3c632Sopenharmony_ci const entryArray = storage.get(fieldNumber).getIndexArray(); 48ffe3c632Sopenharmony_ci expect(entryArray).not.toBeUndefined(); 49ffe3c632Sopenharmony_ci expect(entryArray.length).toBe(expectedEntries.length); 50ffe3c632Sopenharmony_ci 51ffe3c632Sopenharmony_ci for (let i = 0; i < entryArray.length; i++) { 52ffe3c632Sopenharmony_ci const storageEntry = entryArray[i]; 53ffe3c632Sopenharmony_ci const expectedEntry = expectedEntries[i]; 54ffe3c632Sopenharmony_ci 55ffe3c632Sopenharmony_ci expect(storageEntry).toBe(expectedEntry); 56ffe3c632Sopenharmony_ci } 57ffe3c632Sopenharmony_ci} 58ffe3c632Sopenharmony_ci 59ffe3c632Sopenharmony_cidescribe('Indexer does', () => { 60ffe3c632Sopenharmony_ci it('return empty storage for empty array', () => { 61ffe3c632Sopenharmony_ci const storage = buildIndex(createBufferDecoder(), PIVOT); 62ffe3c632Sopenharmony_ci expect(storage).not.toBeNull(); 63ffe3c632Sopenharmony_ci expect(getStorageSize(storage)).toBe(0); 64ffe3c632Sopenharmony_ci }); 65ffe3c632Sopenharmony_ci 66ffe3c632Sopenharmony_ci it('throw for null array', () => { 67ffe3c632Sopenharmony_ci expect( 68ffe3c632Sopenharmony_ci () => buildIndex( 69ffe3c632Sopenharmony_ci /** @type {!BufferDecoder} */ (/** @type {*} */ (null)), PIVOT)) 70ffe3c632Sopenharmony_ci .toThrow(); 71ffe3c632Sopenharmony_ci }); 72ffe3c632Sopenharmony_ci 73ffe3c632Sopenharmony_ci it('fail for invalid wire type (6)', () => { 74ffe3c632Sopenharmony_ci expect(() => buildIndex(createBufferDecoder(0x0E, 0x01), PIVOT)) 75ffe3c632Sopenharmony_ci .toThrowError('Unexpected wire type: 6'); 76ffe3c632Sopenharmony_ci }); 77ffe3c632Sopenharmony_ci 78ffe3c632Sopenharmony_ci it('fail for invalid wire type (7)', () => { 79ffe3c632Sopenharmony_ci expect(() => buildIndex(createBufferDecoder(0x0F, 0x01), PIVOT)) 80ffe3c632Sopenharmony_ci .toThrowError('Unexpected wire type: 7'); 81ffe3c632Sopenharmony_ci }); 82ffe3c632Sopenharmony_ci 83ffe3c632Sopenharmony_ci it('index varint', () => { 84ffe3c632Sopenharmony_ci const data = createBufferDecoder(0x08, 0x01, 0x08, 0x01); 85ffe3c632Sopenharmony_ci const storage = buildIndex(data, PIVOT); 86ffe3c632Sopenharmony_ci assertStorageEntries( 87ffe3c632Sopenharmony_ci storage, /* fieldNumber= */ 1, 88ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.VARINT, /* startIndex= */ 1), 89ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.VARINT, /* startIndex= */ 3)); 90ffe3c632Sopenharmony_ci }); 91ffe3c632Sopenharmony_ci 92ffe3c632Sopenharmony_ci it('index varint with two bytes field number', () => { 93ffe3c632Sopenharmony_ci const data = createBufferDecoder(0xF8, 0x01, 0x01); 94ffe3c632Sopenharmony_ci const storage = buildIndex(data, PIVOT); 95ffe3c632Sopenharmony_ci assertStorageEntries( 96ffe3c632Sopenharmony_ci storage, /* fieldNumber= */ 31, 97ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.VARINT, /* startIndex= */ 2)); 98ffe3c632Sopenharmony_ci }); 99ffe3c632Sopenharmony_ci 100ffe3c632Sopenharmony_ci it('fail for varints that are longer than 10 bytes', () => { 101ffe3c632Sopenharmony_ci const data = createBufferDecoder( 102ffe3c632Sopenharmony_ci 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00); 103ffe3c632Sopenharmony_ci if (CHECK_CRITICAL_STATE) { 104ffe3c632Sopenharmony_ci expect(() => buildIndex(data, PIVOT)) 105ffe3c632Sopenharmony_ci .toThrowError('Index out of bounds: index: 12 size: 11'); 106ffe3c632Sopenharmony_ci } else { 107ffe3c632Sopenharmony_ci // Note in unchecked mode we produce invalid output for invalid inputs. 108ffe3c632Sopenharmony_ci // This test just documents our behavior in those cases. 109ffe3c632Sopenharmony_ci // These values might change at any point and are not considered 110ffe3c632Sopenharmony_ci // what the implementation should be doing here. 111ffe3c632Sopenharmony_ci const storage = buildIndex(data, PIVOT); 112ffe3c632Sopenharmony_ci assertStorageEntries( 113ffe3c632Sopenharmony_ci storage, /* fieldNumber= */ 1, 114ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.VARINT, /* startIndex= */ 1)); 115ffe3c632Sopenharmony_ci } 116ffe3c632Sopenharmony_ci }); 117ffe3c632Sopenharmony_ci 118ffe3c632Sopenharmony_ci it('fail for varints with no data', () => { 119ffe3c632Sopenharmony_ci const data = createBufferDecoder(0x08); 120ffe3c632Sopenharmony_ci expect(() => buildIndex(data, PIVOT)).toThrow(); 121ffe3c632Sopenharmony_ci }); 122ffe3c632Sopenharmony_ci 123ffe3c632Sopenharmony_ci it('index fixed64', () => { 124ffe3c632Sopenharmony_ci const data = createBufferDecoder( 125ffe3c632Sopenharmony_ci /* first= */ 0x09, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 126ffe3c632Sopenharmony_ci /* second= */ 0x09, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08); 127ffe3c632Sopenharmony_ci const storage = buildIndex(data, PIVOT); 128ffe3c632Sopenharmony_ci assertStorageEntries( 129ffe3c632Sopenharmony_ci storage, /* fieldNumber= */ 1, 130ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.FIXED64, /* startIndex= */ 1), 131ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.FIXED64, /* startIndex= */ 10)); 132ffe3c632Sopenharmony_ci }); 133ffe3c632Sopenharmony_ci 134ffe3c632Sopenharmony_ci it('fail for fixed64 data missing in input', () => { 135ffe3c632Sopenharmony_ci const data = 136ffe3c632Sopenharmony_ci createBufferDecoder(0x09, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07); 137ffe3c632Sopenharmony_ci if (CHECK_CRITICAL_STATE) { 138ffe3c632Sopenharmony_ci expect(() => buildIndex(data, PIVOT)) 139ffe3c632Sopenharmony_ci .toThrowError('Index out of bounds: index: 9 size: 8'); 140ffe3c632Sopenharmony_ci } else { 141ffe3c632Sopenharmony_ci // Note in unchecked mode we produce invalid output for invalid inputs. 142ffe3c632Sopenharmony_ci // This test just documents our behavior in those cases. 143ffe3c632Sopenharmony_ci // These values might change at any point and are not considered 144ffe3c632Sopenharmony_ci // what the implementation should be doing here. 145ffe3c632Sopenharmony_ci const storage = buildIndex(data, PIVOT); 146ffe3c632Sopenharmony_ci assertStorageEntries( 147ffe3c632Sopenharmony_ci storage, /* fieldNumber= */ 1, 148ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.FIXED64, /* startIndex= */ 1)); 149ffe3c632Sopenharmony_ci } 150ffe3c632Sopenharmony_ci }); 151ffe3c632Sopenharmony_ci 152ffe3c632Sopenharmony_ci it('fail for fixed64 tag that has no data after it', () => { 153ffe3c632Sopenharmony_ci if (CHECK_CRITICAL_STATE) { 154ffe3c632Sopenharmony_ci const data = createBufferDecoder(0x09); 155ffe3c632Sopenharmony_ci expect(() => buildIndex(data, PIVOT)) 156ffe3c632Sopenharmony_ci .toThrowError('Index out of bounds: index: 9 size: 1'); 157ffe3c632Sopenharmony_ci } else { 158ffe3c632Sopenharmony_ci // Note in unchecked mode we produce invalid output for invalid inputs. 159ffe3c632Sopenharmony_ci // This test just documents our behavior in those cases. 160ffe3c632Sopenharmony_ci // These values might change at any point and are not considered 161ffe3c632Sopenharmony_ci // what the implementation should be doing here. 162ffe3c632Sopenharmony_ci const data = createBufferDecoder(0x09); 163ffe3c632Sopenharmony_ci const storage = buildIndex(data, PIVOT); 164ffe3c632Sopenharmony_ci assertStorageEntries( 165ffe3c632Sopenharmony_ci storage, /* fieldNumber= */ 1, 166ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.FIXED64, /* startIndex= */ 1)); 167ffe3c632Sopenharmony_ci } 168ffe3c632Sopenharmony_ci }); 169ffe3c632Sopenharmony_ci 170ffe3c632Sopenharmony_ci it('index delimited', () => { 171ffe3c632Sopenharmony_ci const data = createBufferDecoder( 172ffe3c632Sopenharmony_ci /* first= */ 0x0A, 0x02, 0x00, 0x01, /* second= */ 0x0A, 0x02, 0x00, 173ffe3c632Sopenharmony_ci 0x01); 174ffe3c632Sopenharmony_ci const storage = buildIndex(data, PIVOT); 175ffe3c632Sopenharmony_ci assertStorageEntries( 176ffe3c632Sopenharmony_ci storage, /* fieldNumber= */ 1, 177ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.DELIMITED, /* startIndex= */ 1), 178ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.DELIMITED, /* startIndex= */ 5)); 179ffe3c632Sopenharmony_ci }); 180ffe3c632Sopenharmony_ci 181ffe3c632Sopenharmony_ci it('fail for length deliimted field data missing in input', () => { 182ffe3c632Sopenharmony_ci const data = createBufferDecoder(0x0A, 0x04, 0x00, 0x01); 183ffe3c632Sopenharmony_ci if (CHECK_CRITICAL_STATE) { 184ffe3c632Sopenharmony_ci expect(() => buildIndex(data, PIVOT)) 185ffe3c632Sopenharmony_ci .toThrowError('Index out of bounds: index: 6 size: 4'); 186ffe3c632Sopenharmony_ci } else { 187ffe3c632Sopenharmony_ci // Note in unchecked mode we produce invalid output for invalid inputs. 188ffe3c632Sopenharmony_ci // This test just documents our behavior in those cases. 189ffe3c632Sopenharmony_ci // These values might change at any point and are not considered 190ffe3c632Sopenharmony_ci // what the implementation should be doing here. 191ffe3c632Sopenharmony_ci const storage = buildIndex(data, PIVOT); 192ffe3c632Sopenharmony_ci assertStorageEntries( 193ffe3c632Sopenharmony_ci storage, /* fieldNumber= */ 1, 194ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.DELIMITED, /* startIndex= */ 1)); 195ffe3c632Sopenharmony_ci } 196ffe3c632Sopenharmony_ci }); 197ffe3c632Sopenharmony_ci 198ffe3c632Sopenharmony_ci it('fail for delimited tag that has no data after it', () => { 199ffe3c632Sopenharmony_ci const data = createBufferDecoder(0x0A); 200ffe3c632Sopenharmony_ci expect(() => buildIndex(data, PIVOT)).toThrow(); 201ffe3c632Sopenharmony_ci }); 202ffe3c632Sopenharmony_ci 203ffe3c632Sopenharmony_ci it('index fixed32', () => { 204ffe3c632Sopenharmony_ci const data = createBufferDecoder( 205ffe3c632Sopenharmony_ci /* first= */ 0x0D, 0x01, 0x02, 0x03, 0x04, /* second= */ 0x0D, 0x01, 206ffe3c632Sopenharmony_ci 0x02, 0x03, 0x04); 207ffe3c632Sopenharmony_ci const storage = buildIndex(data, PIVOT); 208ffe3c632Sopenharmony_ci assertStorageEntries( 209ffe3c632Sopenharmony_ci storage, /* fieldNumber= */ 1, 210ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.FIXED32, /* startIndex= */ 1), 211ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.FIXED32, /* startIndex= */ 6)); 212ffe3c632Sopenharmony_ci }); 213ffe3c632Sopenharmony_ci 214ffe3c632Sopenharmony_ci it('fail for fixed32 data missing in input', () => { 215ffe3c632Sopenharmony_ci const data = createBufferDecoder(0x0D, 0x01, 0x02, 0x03); 216ffe3c632Sopenharmony_ci 217ffe3c632Sopenharmony_ci if (CHECK_CRITICAL_STATE) { 218ffe3c632Sopenharmony_ci expect(() => buildIndex(data, PIVOT)) 219ffe3c632Sopenharmony_ci .toThrowError('Index out of bounds: index: 5 size: 4'); 220ffe3c632Sopenharmony_ci } else { 221ffe3c632Sopenharmony_ci // Note in unchecked mode we produce invalid output for invalid inputs. 222ffe3c632Sopenharmony_ci // This test just documents our behavior in those cases. 223ffe3c632Sopenharmony_ci // These values might change at any point and are not considered 224ffe3c632Sopenharmony_ci // what the implementation should be doing here. 225ffe3c632Sopenharmony_ci const storage = buildIndex(data, PIVOT); 226ffe3c632Sopenharmony_ci assertStorageEntries( 227ffe3c632Sopenharmony_ci storage, /* fieldNumber= */ 1, 228ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.FIXED32, /* startIndex= */ 1)); 229ffe3c632Sopenharmony_ci } 230ffe3c632Sopenharmony_ci }); 231ffe3c632Sopenharmony_ci 232ffe3c632Sopenharmony_ci it('fail for fixed32 tag that has no data after it', () => { 233ffe3c632Sopenharmony_ci if (CHECK_CRITICAL_STATE) { 234ffe3c632Sopenharmony_ci const data = createBufferDecoder(0x0D); 235ffe3c632Sopenharmony_ci expect(() => buildIndex(data, PIVOT)) 236ffe3c632Sopenharmony_ci .toThrowError('Index out of bounds: index: 5 size: 1'); 237ffe3c632Sopenharmony_ci } else { 238ffe3c632Sopenharmony_ci // Note in unchecked mode we produce invalid output for invalid inputs. 239ffe3c632Sopenharmony_ci // This test just documents our behavior in those cases. 240ffe3c632Sopenharmony_ci // These values might change at any point and are not considered 241ffe3c632Sopenharmony_ci // what the implementation should be doing here. 242ffe3c632Sopenharmony_ci const data = createBufferDecoder(0x0D); 243ffe3c632Sopenharmony_ci const storage = buildIndex(data, PIVOT); 244ffe3c632Sopenharmony_ci assertStorageEntries( 245ffe3c632Sopenharmony_ci storage, /* fieldNumber= */ 1, 246ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.FIXED32, /* startIndex= */ 1)); 247ffe3c632Sopenharmony_ci } 248ffe3c632Sopenharmony_ci }); 249ffe3c632Sopenharmony_ci 250ffe3c632Sopenharmony_ci it('index group', () => { 251ffe3c632Sopenharmony_ci const data = createBufferDecoder( 252ffe3c632Sopenharmony_ci /* first= */ 0x0B, 0x08, 0x01, 0x0C, /* second= */ 0x0B, 0x08, 0x01, 253ffe3c632Sopenharmony_ci 0x0C); 254ffe3c632Sopenharmony_ci const storage = buildIndex(data, PIVOT); 255ffe3c632Sopenharmony_ci assertStorageEntries( 256ffe3c632Sopenharmony_ci storage, /* fieldNumber= */ 1, 257ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 1), 258ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 5)); 259ffe3c632Sopenharmony_ci }); 260ffe3c632Sopenharmony_ci 261ffe3c632Sopenharmony_ci it('index group and skips inner group', () => { 262ffe3c632Sopenharmony_ci const data = 263ffe3c632Sopenharmony_ci createBufferDecoder(0x0B, 0x0B, 0x08, 0x01, 0x0C, 0x08, 0x01, 0x0C); 264ffe3c632Sopenharmony_ci const storage = buildIndex(data, PIVOT); 265ffe3c632Sopenharmony_ci assertStorageEntries( 266ffe3c632Sopenharmony_ci storage, /* fieldNumber= */ 1, 267ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 1)); 268ffe3c632Sopenharmony_ci }); 269ffe3c632Sopenharmony_ci 270ffe3c632Sopenharmony_ci it('fail on unmatched stop group', () => { 271ffe3c632Sopenharmony_ci const data = createBufferDecoder(0x0C, 0x01); 272ffe3c632Sopenharmony_ci expect(() => buildIndex(data, PIVOT)) 273ffe3c632Sopenharmony_ci .toThrowError('Unexpected wire type: 4'); 274ffe3c632Sopenharmony_ci }); 275ffe3c632Sopenharmony_ci 276ffe3c632Sopenharmony_ci it('fail for groups without matching stop group', () => { 277ffe3c632Sopenharmony_ci const data = createBufferDecoder(0x0B, 0x08, 0x01, 0x1C); 278ffe3c632Sopenharmony_ci if (CHECK_CRITICAL_STATE) { 279ffe3c632Sopenharmony_ci expect(() => buildIndex(data, PIVOT)) 280ffe3c632Sopenharmony_ci .toThrowError('Expected stop group for fieldnumber 1 not found.'); 281ffe3c632Sopenharmony_ci } else { 282ffe3c632Sopenharmony_ci // Note in unchecked mode we produce invalid output for invalid inputs. 283ffe3c632Sopenharmony_ci // This test just documents our behavior in those cases. 284ffe3c632Sopenharmony_ci // These values might change at any point and are not considered 285ffe3c632Sopenharmony_ci // what the implementation should be doing here. 286ffe3c632Sopenharmony_ci const storage = buildIndex(data, PIVOT); 287ffe3c632Sopenharmony_ci assertStorageEntries( 288ffe3c632Sopenharmony_ci storage, /* fieldNumber= */ 1, 289ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 1)); 290ffe3c632Sopenharmony_ci } 291ffe3c632Sopenharmony_ci }); 292ffe3c632Sopenharmony_ci 293ffe3c632Sopenharmony_ci it('fail for groups without stop group', () => { 294ffe3c632Sopenharmony_ci const data = createBufferDecoder(0x0B, 0x08, 0x01); 295ffe3c632Sopenharmony_ci if (CHECK_CRITICAL_STATE) { 296ffe3c632Sopenharmony_ci expect(() => buildIndex(data, PIVOT)).toThrowError('No end group found.'); 297ffe3c632Sopenharmony_ci } else { 298ffe3c632Sopenharmony_ci // Note in unchecked mode we produce invalid output for invalid inputs. 299ffe3c632Sopenharmony_ci // This test just documents our behavior in those cases. 300ffe3c632Sopenharmony_ci // These values might change at any point and are not considered 301ffe3c632Sopenharmony_ci // what the implementation should be doing here. 302ffe3c632Sopenharmony_ci const storage = buildIndex(data, PIVOT); 303ffe3c632Sopenharmony_ci assertStorageEntries( 304ffe3c632Sopenharmony_ci storage, /* fieldNumber= */ 1, 305ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 1)); 306ffe3c632Sopenharmony_ci } 307ffe3c632Sopenharmony_ci }); 308ffe3c632Sopenharmony_ci 309ffe3c632Sopenharmony_ci it('fail for group tag that has no data after it', () => { 310ffe3c632Sopenharmony_ci const data = createBufferDecoder(0x0B); 311ffe3c632Sopenharmony_ci if (CHECK_CRITICAL_STATE) { 312ffe3c632Sopenharmony_ci expect(() => buildIndex(data, PIVOT)).toThrowError('No end group found.'); 313ffe3c632Sopenharmony_ci } else { 314ffe3c632Sopenharmony_ci // Note in unchecked mode we produce invalid output for invalid inputs. 315ffe3c632Sopenharmony_ci // This test just documents our behavior in those cases. 316ffe3c632Sopenharmony_ci // These values might change at any point and are not considered 317ffe3c632Sopenharmony_ci // what the implementation should be doing here. 318ffe3c632Sopenharmony_ci const storage = buildIndex(data, PIVOT); 319ffe3c632Sopenharmony_ci assertStorageEntries( 320ffe3c632Sopenharmony_ci storage, /* fieldNumber= */ 1, 321ffe3c632Sopenharmony_ci Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 1)); 322ffe3c632Sopenharmony_ci } 323ffe3c632Sopenharmony_ci }); 324ffe3c632Sopenharmony_ci 325ffe3c632Sopenharmony_ci it('index too large tag', () => { 326ffe3c632Sopenharmony_ci const data = createBufferDecoder(0xF8, 0xFF, 0xFF, 0xFF, 0xFF); 327ffe3c632Sopenharmony_ci expect(() => buildIndex(data, PIVOT)).toThrow(); 328ffe3c632Sopenharmony_ci }); 329ffe3c632Sopenharmony_ci 330ffe3c632Sopenharmony_ci it('fail for varint tag that has no data after it', () => { 331ffe3c632Sopenharmony_ci const data = createBufferDecoder(0x08); 332ffe3c632Sopenharmony_ci expect(() => buildIndex(data, PIVOT)).toThrow(); 333ffe3c632Sopenharmony_ci }); 334ffe3c632Sopenharmony_ci}); 335