message_set_test.js 8.5 KB

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