1/** 2 * @fileoverview Tests for BufferDecoder. 3 */ 4 5goog.module('protobuf.binary.varintsTest'); 6 7const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); 8const {CHECK_CRITICAL_STATE, CHECK_STATE} = goog.require('protobuf.internal.checks'); 9 10goog.setTestOnly(); 11 12/** 13 * @param {...number} bytes 14 * @return {!ArrayBuffer} 15 */ 16function createArrayBuffer(...bytes) { 17 return new Uint8Array(bytes).buffer; 18} 19 20describe('setCursor does', () => { 21 it('set the cursor at the position specified', () => { 22 const bufferDecoder = 23 BufferDecoder.fromArrayBuffer(createArrayBuffer(0x0, 0x1)); 24 expect(bufferDecoder.cursor()).toBe(0); 25 bufferDecoder.setCursor(1); 26 expect(bufferDecoder.cursor()).toBe(1); 27 }); 28}); 29 30describe('skip does', () => { 31 it('advance the cursor', () => { 32 const bufferDecoder = 33 BufferDecoder.fromArrayBuffer(createArrayBuffer(0x0, 0x1, 0x2)); 34 bufferDecoder.setCursor(1); 35 bufferDecoder.skip(1); 36 expect(bufferDecoder.cursor()).toBe(2); 37 }); 38}); 39 40describe('Skip varint does', () => { 41 it('skip a varint', () => { 42 const bufferDecoder = 43 BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01)); 44 bufferDecoder.skipVarint(); 45 expect(bufferDecoder.cursor()).toBe(1); 46 }); 47 48 it('fail when varint is larger than 10 bytes', () => { 49 const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer( 50 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); 51 52 if (CHECK_CRITICAL_STATE) { 53 expect(() => bufferDecoder.skipVarint()).toThrow(); 54 } else { 55 // Note in unchecked mode we produce invalid output for invalid inputs. 56 // This test just documents our behavior in those cases. 57 // These values might change at any point and are not considered 58 // what the implementation should be doing here. 59 bufferDecoder.skipVarint(); 60 expect(bufferDecoder.cursor()).toBe(11); 61 } 62 }); 63 64 it('fail when varint is beyond end of underlying array', () => { 65 const bufferDecoder = 66 BufferDecoder.fromArrayBuffer(createArrayBuffer(0x80, 0x80)); 67 expect(() => bufferDecoder.skipVarint()).toThrow(); 68 }); 69}); 70 71describe('readVarint64 does', () => { 72 it('read zero', () => { 73 const bufferDecoder = 74 BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00)); 75 const {lowBits, highBits} = bufferDecoder.getVarint(0); 76 expect(lowBits).toBe(0); 77 expect(highBits).toBe(0); 78 expect(bufferDecoder.cursor()).toBe(1); 79 }); 80 81 it('read one', () => { 82 const bufferDecoder = 83 BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01)); 84 const {lowBits, highBits} = bufferDecoder.getVarint(0); 85 expect(lowBits).toBe(1); 86 expect(highBits).toBe(0); 87 expect(bufferDecoder.cursor()).toBe(1); 88 }); 89 90 it('read max value', () => { 91 const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer( 92 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01)); 93 const {lowBits, highBits} = bufferDecoder.getVarint(0); 94 expect(lowBits).toBe(-1); 95 expect(highBits).toBe(-1); 96 expect(bufferDecoder.cursor()).toBe(10); 97 }); 98}); 99 100describe('readUnsignedVarint32 does', () => { 101 it('read zero', () => { 102 const bufferDecoder = 103 BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00)); 104 const result = bufferDecoder.getUnsignedVarint32(); 105 expect(result).toBe(0); 106 expect(bufferDecoder.cursor()).toBe(1); 107 }); 108 109 it('read one', () => { 110 const bufferDecoder = 111 BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01)); 112 const result = bufferDecoder.getUnsignedVarint32(); 113 expect(result).toBe(1); 114 expect(bufferDecoder.cursor()).toBe(1); 115 }); 116 117 it('read max int32', () => { 118 const bufferDecoder = BufferDecoder.fromArrayBuffer( 119 createArrayBuffer(0xFF, 0xFF, 0xFF, 0xFF, 0x0F)); 120 const result = bufferDecoder.getUnsignedVarint32(); 121 expect(result).toBe(4294967295); 122 expect(bufferDecoder.cursor()).toBe(5); 123 }); 124 125 it('read max value', () => { 126 const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer( 127 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01)); 128 const result = bufferDecoder.getUnsignedVarint32(); 129 expect(result).toBe(4294967295); 130 expect(bufferDecoder.cursor()).toBe(10); 131 }); 132 133 it('fail if data is longer than 10 bytes', () => { 134 const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer( 135 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01)); 136 if (CHECK_CRITICAL_STATE) { 137 expect(() => bufferDecoder.getUnsignedVarint32()).toThrow(); 138 } else { 139 // Note in unchecked mode we produce invalid output for invalid inputs. 140 // This test just documents our behavior in those cases. 141 // These values might change at any point and are not considered 142 // what the implementation should be doing here. 143 const result = bufferDecoder.getUnsignedVarint32(); 144 expect(result).toBe(4294967295); 145 expect(bufferDecoder.cursor()).toBe(10); 146 } 147 }); 148}); 149 150describe('readUnsignedVarint32At does', () => { 151 it('reads from a specific index', () => { 152 const bufferDecoder = 153 BufferDecoder.fromArrayBuffer(createArrayBuffer(0x1, 0x2)); 154 const result = bufferDecoder.getUnsignedVarint32At(1); 155 expect(result).toBe(2); 156 expect(bufferDecoder.cursor()).toBe(2); 157 }); 158}); 159 160describe('getFloat32 does', () => { 161 it('read one', () => { 162 const bufferDecoder = BufferDecoder.fromArrayBuffer( 163 createArrayBuffer(0x00, 0x00, 0x80, 0x3F)); 164 const result = bufferDecoder.getFloat32(0); 165 expect(result).toBe(1); 166 expect(bufferDecoder.cursor()).toBe(4); 167 }); 168}); 169 170describe('getFloat64 does', () => { 171 it('read one', () => { 172 const bufferDecoder = BufferDecoder.fromArrayBuffer( 173 createArrayBuffer(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F)); 174 const result = bufferDecoder.getFloat64(0); 175 expect(result).toBe(1); 176 expect(bufferDecoder.cursor()).toBe(8); 177 }); 178}); 179 180describe('getInt32 does', () => { 181 it('read one', () => { 182 const bufferDecoder = BufferDecoder.fromArrayBuffer( 183 createArrayBuffer(0x01, 0x00, 0x00, 0x00)); 184 const result = bufferDecoder.getInt32(0); 185 expect(result).toBe(1); 186 expect(bufferDecoder.cursor()).toBe(4); 187 }); 188 189 it('read minus one', () => { 190 const bufferDecoder = BufferDecoder.fromArrayBuffer( 191 createArrayBuffer(0xFF, 0xFF, 0xFF, 0xFF)); 192 const result = bufferDecoder.getInt32(0); 193 expect(result).toBe(-1); 194 expect(bufferDecoder.cursor()).toBe(4); 195 }); 196}); 197 198describe('getUint32 does', () => { 199 it('read one', () => { 200 const bufferDecoder = 201 BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01, 0x00, 0x00, 0x0)); 202 const result = bufferDecoder.getUint32(0); 203 expect(result).toBe(1); 204 expect(bufferDecoder.cursor()).toBe(4); 205 }); 206 207 it('read max uint32', () => { 208 const bufferDecoder = BufferDecoder.fromArrayBuffer( 209 createArrayBuffer(0xFF, 0xFF, 0xFF, 0xFF)); 210 const result = bufferDecoder.getUint32(0); 211 expect(result).toBe(4294967295); 212 expect(bufferDecoder.cursor()).toBe(4); 213 }); 214}); 215 216describe('subBufferDecoder does', () => { 217 it('can create valid sub buffers', () => { 218 const bufferDecoder = 219 BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00, 0x01, 0x02)); 220 221 expect(bufferDecoder.subBufferDecoder(0, 0)) 222 .toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer())); 223 expect(bufferDecoder.subBufferDecoder(0, 1)) 224 .toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00))); 225 expect(bufferDecoder.subBufferDecoder(1, 0)) 226 .toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer())); 227 expect(bufferDecoder.subBufferDecoder(1, 1)) 228 .toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01))); 229 expect(bufferDecoder.subBufferDecoder(1, 2)) 230 .toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01, 0x02))); 231 }); 232 233 it('can not create invalid', () => { 234 const bufferDecoder = 235 BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00, 0x01, 0x02)); 236 if (CHECK_STATE) { 237 expect(() => bufferDecoder.subBufferDecoder(-1, 1)).toThrow(); 238 expect(() => bufferDecoder.subBufferDecoder(0, -4)).toThrow(); 239 expect(() => bufferDecoder.subBufferDecoder(0, 4)).toThrow(); 240 } 241 }); 242}); 243