1/** 2 * @fileoverview Tests for message_set.js. 3 */ 4goog.module('protobuf.runtime.MessageSetTest'); 5 6goog.setTestOnly(); 7 8const Kernel = goog.require('protobuf.runtime.Kernel'); 9const MessageSet = goog.require('protobuf.runtime.MessageSet'); 10const TestMessage = goog.require('protobuf.testing.binary.TestMessage'); 11 12/** 13 * @param {...number} bytes 14 * @return {!ArrayBuffer} 15 */ 16function createArrayBuffer(...bytes) { 17 return new Uint8Array(bytes).buffer; 18} 19 20describe('MessageSet does', () => { 21 it('returns no messages for empty set', () => { 22 const messageSet = MessageSet.createEmpty(); 23 expect(messageSet.getMessageOrNull(12345, TestMessage.instanceCreator)) 24 .toBeNull(); 25 }); 26 27 it('returns no kernel for empty set', () => { 28 const messageSet = MessageSet.createEmpty(); 29 expect(messageSet.getMessageAccessorOrNull(12345)).toBeNull(); 30 }); 31 32 it('returns message that has been set', () => { 33 const messageSet = MessageSet.createEmpty(); 34 const message = TestMessage.createEmpty(); 35 messageSet.setMessage(12345, message); 36 expect(messageSet.getMessageOrNull(12345, TestMessage.instanceCreator)) 37 .toBe(message); 38 }); 39 40 it('returns null for cleared message', () => { 41 const messageSet = MessageSet.createEmpty(); 42 const message = TestMessage.createEmpty(); 43 messageSet.setMessage(12345, message); 44 messageSet.clearMessage(12345); 45 expect(messageSet.getMessageAccessorOrNull(12345)).toBeNull(); 46 }); 47 48 it('returns false for not present message', () => { 49 const messageSet = MessageSet.createEmpty(); 50 expect(messageSet.hasMessage(12345)).toBe(false); 51 }); 52 53 it('returns true for present message', () => { 54 const messageSet = MessageSet.createEmpty(); 55 const message = TestMessage.createEmpty(); 56 messageSet.setMessage(12345, message); 57 expect(messageSet.hasMessage(12345)).toBe(true); 58 }); 59 60 it('returns false for cleared message', () => { 61 const messageSet = MessageSet.createEmpty(); 62 const message = TestMessage.createEmpty(); 63 messageSet.setMessage(12345, message); 64 messageSet.clearMessage(12345); 65 expect(messageSet.hasMessage(12345)).toBe(false); 66 }); 67 68 it('returns false for cleared message without it being present', () => { 69 const messageSet = MessageSet.createEmpty(); 70 messageSet.clearMessage(12345); 71 expect(messageSet.hasMessage(12345)).toBe(false); 72 }); 73 74 const createMessageSet = () => { 75 const messageSet = MessageSet.createEmpty(); 76 const message = TestMessage.createEmpty(); 77 message.setInt32(1, 2); 78 messageSet.setMessage(12345, message); 79 80 81 const parsedKernel = 82 Kernel.fromArrayBuffer(messageSet.internalGetKernel().serialize()); 83 return MessageSet.fromKernel(parsedKernel); 84 }; 85 86 it('pass through pivot for getMessageOrNull', () => { 87 const messageSet = createMessageSet(); 88 const message = 89 messageSet.getMessageOrNull(12345, TestMessage.instanceCreator, 2); 90 expect(message.internalGetKernel().getPivot()).toBe(2); 91 }); 92 93 it('pass through pivot for getMessageAttach', () => { 94 const messageSet = createMessageSet(); 95 const message = 96 messageSet.getMessageAttach(12345, TestMessage.instanceCreator, 2); 97 expect(message.internalGetKernel().getPivot()).toBe(2); 98 }); 99 100 it('pass through pivot for getMessageAccessorOrNull', () => { 101 const messageSet = createMessageSet(); 102 const kernel = messageSet.getMessageAccessorOrNull(12345, 2); 103 expect(kernel.getPivot()).toBe(2); 104 }); 105 106 it('pick the last value in the stream', () => { 107 const arrayBuffer = createArrayBuffer( 108 0x52, // Tag (field:10, length delimited) 109 0x14, // Length of 20 bytes 110 0x0B, // Start group fieldnumber 1 111 0x10, // Tag (field 2, varint) 112 0xB9, // 12345 113 0x60, // 12345 114 0x1A, // Tag (field 3, length delimited) 115 0x03, // length 3 116 0xA0, // Tag (fieldnumber 20, varint) 117 0x01, // Tag (fieldnumber 20, varint) 118 0x1E, // 30 119 0x0C, // Stop Group field number 1 120 // second group 121 0x0B, // Start group fieldnumber 1 122 0x10, // Tag (field 2, varint) 123 0xB9, // 12345 124 0x60, // 12345 125 0x1A, // Tag (field 3, length delimited) 126 0x03, // length 3 127 0xA0, // Tag (fieldnumber 20, varint) 128 0x01, // Tag (fieldnumber 20, varint) 129 0x01, // 1 130 0x0C // Stop Group field number 1 131 ); 132 133 const outerMessage = Kernel.fromArrayBuffer(arrayBuffer); 134 135 const messageSet = outerMessage.getMessage(10, MessageSet.fromKernel); 136 137 const message = 138 messageSet.getMessageOrNull(12345, TestMessage.instanceCreator); 139 expect(message.getInt32WithDefault(20)).toBe(1); 140 }); 141 142 it('removes duplicates when read', () => { 143 const arrayBuffer = createArrayBuffer( 144 0x52, // Tag (field:10, length delimited) 145 0x14, // Length of 20 bytes 146 0x0B, // Start group fieldnumber 1 147 0x10, // Tag (field 2, varint) 148 0xB9, // 12345 149 0x60, // 12345 150 0x1A, // Tag (field 3, length delimited) 151 0x03, // length 3 152 0xA0, // Tag (fieldnumber 20, varint) 153 0x01, // Tag (fieldnumber 20, varint) 154 0x1E, // 30 155 0x0C, // Stop Group field number 1 156 // second group 157 0x0B, // Start group fieldnumber 1 158 0x10, // Tag (field 2, varint) 159 0xB9, // 12345 160 0x60, // 12345 161 0x1A, // Tag (field 3, length delimited) 162 0x03, // length 3 163 0xA0, // Tag (fieldnumber 20, varint) 164 0x01, // Tag (fieldnumber 20, varint) 165 0x01, // 1 166 0x0C // Stop Group field number 1 167 ); 168 169 170 const outerMessage = Kernel.fromArrayBuffer(arrayBuffer); 171 outerMessage.getMessageAttach(10, MessageSet.fromKernel); 172 173 expect(outerMessage.serialize()) 174 .toEqual(createArrayBuffer( 175 0x52, // Tag (field:10, length delimited) 176 0x0A, // Length of 10 bytes 177 0x0B, // Start group fieldnumber 1 178 0x10, // Tag (field 2, varint) 179 0xB9, // 12345 180 0x60, // 12345 181 0x1A, // Tag (field 3, length delimited) 182 0x03, // length 3 183 0xA0, // Tag (fieldnumber 20, varint) 184 0x01, // Tag (fieldnumber 20, varint) 185 0x01, // 1 186 0x0C // Stop Group field number 1 187 )); 188 }); 189 190 it('allow for large typeIds', () => { 191 const messageSet = MessageSet.createEmpty(); 192 const message = TestMessage.createEmpty(); 193 messageSet.setMessage(0xFFFFFFFE >>> 0, message); 194 expect(messageSet.hasMessage(0xFFFFFFFE >>> 0)).toBe(true); 195 }); 196}); 197 198describe('Optional MessageSet does', () => { 199 // message Bar { 200 // optional MessageSet mset = 10; 201 //} 202 // 203 // message Foo { 204 // extend proto2.bridge.MessageSet { 205 // optional Foo message_set_extension = 12345; 206 // } 207 // optional int32 f20 = 20; 208 //} 209 210 it('encode as a field', () => { 211 const fooMessage = Kernel.createEmpty(); 212 fooMessage.setInt32(20, 30); 213 214 const messageSet = MessageSet.createEmpty(); 215 messageSet.setMessage(12345, TestMessage.instanceCreator(fooMessage)); 216 217 const barMessage = Kernel.createEmpty(); 218 barMessage.setMessage(10, messageSet); 219 220 expect(barMessage.serialize()) 221 .toEqual(createArrayBuffer( 222 0x52, // Tag (field:10, length delimited) 223 0x0A, // Length of 10 bytes 224 0x0B, // Start group fieldnumber 1 225 0x10, // Tag (field 2, varint) 226 0xB9, // 12345 227 0x60, // 12345 228 0x1A, // Tag (field 3, length delimited) 229 0x03, // length 3 230 0xA0, // Tag (fieldnumber 20, varint) 231 0x01, // Tag (fieldnumber 20, varint) 232 0x1E, // 30 233 0x0C // Stop Group field number 1 234 )); 235 }); 236 237 it('deserializes', () => { 238 const fooMessage = Kernel.createEmpty(); 239 fooMessage.setInt32(20, 30); 240 241 const messageSet = MessageSet.createEmpty(); 242 messageSet.setMessage(12345, TestMessage.instanceCreator(fooMessage)); 243 244 245 const barMessage = Kernel.createEmpty(); 246 barMessage.setMessage(10, messageSet); 247 248 const arrayBuffer = barMessage.serialize(); 249 250 const barMessageParsed = Kernel.fromArrayBuffer(arrayBuffer); 251 expect(barMessageParsed.hasFieldNumber(10)).toBe(true); 252 253 const messageSetParsed = 254 barMessageParsed.getMessage(10, MessageSet.fromKernel); 255 256 const fooMessageParsed = 257 messageSetParsed.getMessageOrNull(12345, TestMessage.instanceCreator) 258 .internalGetKernel(); 259 260 expect(fooMessageParsed.getInt32WithDefault(20)).toBe(30); 261 }); 262}); 263