1goog.module('proto.im.integration.ByteStringFieldsTest'); 2goog.setTestOnly(); 3 4const ByteString = goog.require('protobuf.ByteString'); 5const {arrayBufferSlice} = goog.require('protobuf.binary.typedArrays'); 6 7const /** !ArrayBuffer */ TEST_BYTES = new Uint8Array([1, 2, 3, 4]).buffer; 8const /** !ByteString */ TEST_STRING = ByteString.fromArrayBuffer(TEST_BYTES); 9const /** !ArrayBuffer */ PREFIXED_TEST_BYTES = 10 new Uint8Array([0, 1, 2, 3, 4]).buffer; 11const /** string */ HALLO_IN_BASE64 = 'aGFsbG8='; 12const /** string */ HALLO_IN_BASE64_WITH_SPACES = 'a G F s b G 8='; 13const /** !ArrayBufferView */ BYTES_WITH_HALLO = new Uint8Array([ 14 'h'.charCodeAt(0), 15 'a'.charCodeAt(0), 16 'l'.charCodeAt(0), 17 'l'.charCodeAt(0), 18 'o'.charCodeAt(0), 19]); 20 21describe('ByteString does', () => { 22 it('create bytestring from buffer', () => { 23 const byteString = 24 ByteString.fromArrayBuffer(arrayBufferSlice(TEST_BYTES, 0)); 25 expect(byteString.toArrayBuffer()).toEqual(TEST_BYTES); 26 expect(byteString.toUint8ArrayUnsafe()).toEqual(new Uint8Array(TEST_BYTES)); 27 }); 28 29 it('create bytestring from ArrayBufferView', () => { 30 const byteString = 31 ByteString.fromArrayBufferView(new Uint8Array(TEST_BYTES)); 32 expect(byteString.toArrayBuffer()).toEqual(TEST_BYTES); 33 expect(byteString.toUint8ArrayUnsafe()).toEqual(new Uint8Array(TEST_BYTES)); 34 }); 35 36 it('create bytestring from subarray', () => { 37 const byteString = ByteString.fromArrayBufferView( 38 new Uint8Array(TEST_BYTES, /* offset */ 1, /* length */ 2)); 39 const expected = new Uint8Array([2, 3]); 40 expect(new Uint8Array(byteString.toArrayBuffer())).toEqual(expected); 41 expect(byteString.toUint8ArrayUnsafe()).toEqual(expected); 42 }); 43 44 it('create bytestring from Uint8Array (unsafe)', () => { 45 const array = new Uint8Array(TEST_BYTES); 46 const byteString = ByteString.fromUint8ArrayUnsafe(array); 47 expect(byteString.toArrayBuffer()).toEqual(array.buffer); 48 expect(byteString.toUint8ArrayUnsafe()).toBe(array); 49 }); 50 51 it('create bytestring from base64 string', () => { 52 const byteString = ByteString.fromBase64String(HALLO_IN_BASE64); 53 expect(byteString.toBase64String()).toEqual(HALLO_IN_BASE64); 54 expect(byteString.toArrayBuffer()).toEqual(BYTES_WITH_HALLO.buffer); 55 expect(byteString.toUint8ArrayUnsafe()).toEqual(BYTES_WITH_HALLO); 56 }); 57 58 it('preserve immutability if underlying buffer changes: from buffer', () => { 59 const buffer = new ArrayBuffer(4); 60 const array = new Uint8Array(buffer); 61 array[0] = 1; 62 array[1] = 2; 63 array[2] = 3; 64 array[3] = 4; 65 66 const byteString = ByteString.fromArrayBuffer(buffer); 67 const otherBuffer = byteString.toArrayBuffer(); 68 69 expect(otherBuffer).not.toBe(buffer); 70 expect(new Uint8Array(otherBuffer)).toEqual(array); 71 72 // modify the original buffer 73 array[0] = 5; 74 // Are we still returning the original bytes? 75 expect(new Uint8Array(byteString.toArrayBuffer())).toEqual(new Uint8Array([ 76 1, 2, 3, 4 77 ])); 78 }); 79 80 it('preserve immutability if underlying buffer changes: from ArrayBufferView', 81 () => { 82 const buffer = new ArrayBuffer(4); 83 const array = new Uint8Array(buffer); 84 array[0] = 1; 85 array[1] = 2; 86 array[2] = 3; 87 array[3] = 4; 88 89 const byteString = ByteString.fromArrayBufferView(array); 90 const otherBuffer = byteString.toArrayBuffer(); 91 92 expect(otherBuffer).not.toBe(buffer); 93 expect(new Uint8Array(otherBuffer)).toEqual(array); 94 95 // modify the original buffer 96 array[0] = 5; 97 // Are we still returning the original bytes? 98 expect(new Uint8Array(byteString.toArrayBuffer())) 99 .toEqual(new Uint8Array([1, 2, 3, 4])); 100 }); 101 102 it('mutate if underlying buffer changes: from Uint8Array (unsafe)', () => { 103 const buffer = new ArrayBuffer(4); 104 const array = new Uint8Array(buffer); 105 array[0] = 1; 106 array[1] = 2; 107 array[2] = 3; 108 array[3] = 4; 109 110 const byteString = ByteString.fromUint8ArrayUnsafe(array); 111 const otherBuffer = byteString.toArrayBuffer(); 112 113 expect(otherBuffer).not.toBe(buffer); 114 expect(new Uint8Array(otherBuffer)).toEqual(array); 115 116 // modify the original buffer 117 array[0] = 5; 118 // We are no longer returning the original bytes 119 expect(new Uint8Array(byteString.toArrayBuffer())).toEqual(new Uint8Array([ 120 5, 2, 3, 4 121 ])); 122 }); 123 124 it('preserve immutability for returned buffers: toArrayBuffer', () => { 125 const byteString = ByteString.fromArrayBufferView(new Uint8Array(4)); 126 const buffer1 = byteString.toArrayBuffer(); 127 const buffer2 = byteString.toArrayBuffer(); 128 129 expect(buffer1).toEqual(buffer2); 130 131 const array1 = new Uint8Array(buffer1); 132 array1[0] = 1; 133 134 expect(buffer1).not.toEqual(buffer2); 135 }); 136 137 it('does not preserve immutability for returned buffers: toUint8ArrayUnsafe', 138 () => { 139 const byteString = ByteString.fromUint8ArrayUnsafe(new Uint8Array(4)); 140 const array1 = byteString.toUint8ArrayUnsafe(); 141 const array2 = byteString.toUint8ArrayUnsafe(); 142 143 expect(array1).toEqual(array2); 144 array1[0] = 1; 145 146 expect(array1).toEqual(array2); 147 }); 148 149 it('throws when created with null ArrayBufferView', () => { 150 expect( 151 () => ByteString.fromArrayBufferView( 152 /** @type {!ArrayBufferView} */ (/** @type{*} */ (null)))) 153 .toThrow(); 154 }); 155 156 it('throws when created with null buffer', () => { 157 expect( 158 () => ByteString.fromBase64String( 159 /** @type {string} */ (/** @type{*} */ (null)))) 160 .toThrow(); 161 }); 162 163 it('convert base64 to ArrayBuffer', () => { 164 const other = ByteString.fromBase64String(HALLO_IN_BASE64); 165 expect(BYTES_WITH_HALLO).toEqual(new Uint8Array(other.toArrayBuffer())); 166 }); 167 168 it('convert base64 with spaces to ArrayBuffer', () => { 169 const other = ByteString.fromBase64String(HALLO_IN_BASE64_WITH_SPACES); 170 expect(new Uint8Array(other.toArrayBuffer())).toEqual(BYTES_WITH_HALLO); 171 }); 172 173 it('convert bytes to base64', () => { 174 const other = ByteString.fromArrayBufferView(BYTES_WITH_HALLO); 175 expect(HALLO_IN_BASE64).toEqual(other.toBase64String()); 176 }); 177 178 it('equal empty bytetring', () => { 179 const empty = ByteString.fromArrayBuffer(new ArrayBuffer(0)); 180 expect(ByteString.EMPTY.equals(empty)).toEqual(true); 181 }); 182 183 it('equal empty bytestring constructed from ArrayBufferView', () => { 184 const empty = ByteString.fromArrayBufferView(new Uint8Array(0)); 185 expect(ByteString.EMPTY.equals(empty)).toEqual(true); 186 }); 187 188 it('equal empty bytestring constructed from Uint8Array (unsafe)', () => { 189 const empty = ByteString.fromUint8ArrayUnsafe(new Uint8Array(0)); 190 expect(ByteString.EMPTY.equals(empty)).toEqual(true); 191 }); 192 193 it('equal empty bytestring constructed from base64', () => { 194 const empty = ByteString.fromBase64String(''); 195 expect(ByteString.EMPTY.equals(empty)).toEqual(true); 196 }); 197 198 it('equal other instance', () => { 199 const other = ByteString.fromArrayBuffer(arrayBufferSlice(TEST_BYTES, 0)); 200 expect(TEST_STRING.equals(other)).toEqual(true); 201 }); 202 203 it('not equal different instance', () => { 204 const other = 205 ByteString.fromArrayBuffer(new Uint8Array([1, 2, 3, 4, 5]).buffer); 206 expect(TEST_STRING.equals(other)).toEqual(false); 207 }); 208 209 it('equal other instance constructed from ArrayBufferView', () => { 210 const other = 211 ByteString.fromArrayBufferView(new Uint8Array(PREFIXED_TEST_BYTES, 1)); 212 expect(TEST_STRING.equals(other)).toEqual(true); 213 }); 214 215 it('not equal different instance constructed from ArrayBufferView', () => { 216 const other = 217 ByteString.fromArrayBufferView(new Uint8Array([1, 2, 3, 4, 5])); 218 expect(TEST_STRING.equals(other)).toEqual(false); 219 }); 220 221 it('equal other instance constructed from Uint8Array (unsafe)', () => { 222 const other = 223 ByteString.fromUint8ArrayUnsafe(new Uint8Array(PREFIXED_TEST_BYTES, 1)); 224 expect(TEST_STRING.equals(other)).toEqual(true); 225 }); 226 227 it('not equal different instance constructed from Uint8Array (unsafe)', 228 () => { 229 const other = 230 ByteString.fromUint8ArrayUnsafe(new Uint8Array([1, 2, 3, 4, 5])); 231 expect(TEST_STRING.equals(other)).toEqual(false); 232 }); 233 234 it('have same hashcode for empty bytes', () => { 235 const empty = ByteString.fromArrayBuffer(new ArrayBuffer(0)); 236 expect(ByteString.EMPTY.hashCode()).toEqual(empty.hashCode()); 237 }); 238 239 it('have same hashcode for test bytes', () => { 240 const other = ByteString.fromArrayBuffer(arrayBufferSlice(TEST_BYTES, 0)); 241 expect(TEST_STRING.hashCode()).toEqual(other.hashCode()); 242 }); 243 244 it('have same hashcode for test bytes', () => { 245 const other = ByteString.fromArrayBufferView( 246 new Uint8Array(arrayBufferSlice(TEST_BYTES, 0))); 247 expect(TEST_STRING.hashCode()).toEqual(other.hashCode()); 248 }); 249 250 it('have same hashcode for different instance constructed with base64', 251 () => { 252 const other = ByteString.fromBase64String(HALLO_IN_BASE64); 253 expect(ByteString.fromArrayBufferView(BYTES_WITH_HALLO).hashCode()) 254 .toEqual(other.hashCode()); 255 }); 256 257 it('preserves the length of a Uint8Array', () => { 258 const original = new Uint8Array([105, 183, 51, 251, 253, 118, 247]); 259 const afterByteString = new Uint8Array( 260 ByteString.fromArrayBufferView(original).toArrayBuffer()); 261 expect(afterByteString).toEqual(original); 262 }); 263 264 it('preserves the length of a base64 value', () => { 265 const expected = new Uint8Array([105, 183, 51, 251, 253, 118, 247]); 266 const afterByteString = new Uint8Array( 267 ByteString.fromBase64String('abcz+/129w').toArrayBuffer()); 268 expect(afterByteString).toEqual(expected); 269 }); 270 271 it('preserves the length of a base64 value with padding', () => { 272 const expected = new Uint8Array([105, 183, 51, 251, 253, 118, 247]); 273 const afterByteString = new Uint8Array( 274 ByteString.fromBase64String('abcz+/129w==').toArrayBuffer()); 275 expect(afterByteString).toEqual(expected); 276 }); 277}); 278