jsonstreamparser_test.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. // Copyright 2015 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. goog.provide('goog.net.streams.JsonStreamParserTest');
  15. goog.setTestOnly('goog.net.streams.JsonStreamParserTest');
  16. goog.require('goog.array');
  17. goog.require('goog.json');
  18. goog.require('goog.labs.testing.JsonFuzzing');
  19. goog.require('goog.net.streams.JsonStreamParser');
  20. goog.require('goog.testing.asserts');
  21. goog.require('goog.testing.jsunit');
  22. goog.require('goog.uri.utils');
  23. var debug;
  24. function setUp() {
  25. var uri = window.document.URL;
  26. if (uri) {
  27. var debugFlag = goog.uri.utils.getParamValue(uri, 'debug');
  28. if (debugFlag) {
  29. debug = window.document.getElementById('debug');
  30. }
  31. }
  32. }
  33. /**
  34. * Debug is enabled with "&debug=on" on the URL.
  35. *
  36. * @param {string} info The debug info
  37. */
  38. function print(info) {
  39. if (debug) {
  40. debug.innerHTML += '<p><p>' + info;
  41. }
  42. }
  43. function testEmptyStream() {
  44. var parser = new goog.net.streams.JsonStreamParser();
  45. var result = parser.parse('[]');
  46. assertNull(result);
  47. }
  48. function testEmptyStreamMore() {
  49. var parser = new goog.net.streams.JsonStreamParser();
  50. var result = parser.parse(' [ ] ');
  51. assertNull(result);
  52. parser = new goog.net.streams.JsonStreamParser();
  53. result = parser.parse(' [ ');
  54. assertNull(result);
  55. result = parser.parse(' ] ');
  56. assertNull(result);
  57. parser = new goog.net.streams.JsonStreamParser();
  58. assertThrows(function() { parser.parse(' a [ '); });
  59. assertThrows(function() { parser.parse(' [ ] '); });
  60. }
  61. function testSingleMessage() {
  62. var parser = new goog.net.streams.JsonStreamParser();
  63. var result = parser.parse('[{"a" : "b"}]');
  64. assertEquals(1, result.length);
  65. assertEquals('b', result[0].a);
  66. }
  67. function testEnclosingArray() {
  68. var parser = new goog.net.streams.JsonStreamParser();
  69. var result = parser.parse('[\n');
  70. assertNull(result);
  71. result = parser.parse('{"a" : "b"}');
  72. assertEquals(1, result.length);
  73. assertEquals('b', result[0].a);
  74. result = parser.parse('\n]');
  75. assertNull(result);
  76. }
  77. function testSingleMessageInChunks() {
  78. var parser = new goog.net.streams.JsonStreamParser();
  79. var result = parser.parse('[{"a" : ');
  80. assertNull(result);
  81. result = parser.parse('"b"}]');
  82. assertEquals(1, result.length);
  83. assertEquals('b', result[0].a);
  84. parser = new goog.net.streams.JsonStreamParser();
  85. result = parser.parse('[ { "a" : ');
  86. assertNull(result);
  87. result = parser.parse('"b"} ');
  88. assertEquals(1, result.length);
  89. assertEquals('b', result[0].a);
  90. result = parser.parse('] ');
  91. assertNull(result);
  92. }
  93. function testTwoMessages() {
  94. var parser = new goog.net.streams.JsonStreamParser();
  95. var result = parser.parse('[{"a" : "b"}, {"c" : "d"}]');
  96. assertEquals(2, result.length);
  97. assertEquals('b', result[0].a);
  98. assertEquals('d', result[1].c);
  99. }
  100. function testTwoMessagesInChunks() {
  101. var parser = new goog.net.streams.JsonStreamParser();
  102. var result = parser.parse('[{"a" : "b"}, ');
  103. assertEquals(1, result.length);
  104. assertEquals('b', result[0].a);
  105. result = parser.parse('{"c" : "d"} ');
  106. assertEquals(1, result.length);
  107. assertEquals('d', result[0].c);
  108. result = parser.parse('] ');
  109. assertNull(result);
  110. assertThrows(function() { parser.parse(' a '); });
  111. }
  112. /**
  113. * Parse a fuzzy json string only once.
  114. */
  115. function testSingleFuzzyMessages() {
  116. var fuzzing = new goog.labs.testing.JsonFuzzing();
  117. // total # of tests
  118. for (var i = 0; i < 5; i++) {
  119. var data = fuzzing.newArray();
  120. var dataString = goog.json.serialize(data);
  121. var parser = new goog.net.streams.JsonStreamParser();
  122. var result = parser.parse(dataString);
  123. assertEquals(data.length, result.length);
  124. goog.array.forEach(data, function(elm, index) {
  125. assertNotNull(elm);
  126. assertObjectEquals(dataString, elm, result[index]);
  127. });
  128. }
  129. }
  130. /**
  131. * Parse a fuzzy json string split (in two chunks) at each index of the string.
  132. *
  133. * This is a VERY expensive test, so change the fuzzing options for manual runs
  134. * as required.
  135. */
  136. function testChunkedFuzzyMessages() {
  137. var options = {jsonSize: 5, numFields: 5, arraySize: 4, maxDepth: 3};
  138. var fuzzing = new goog.labs.testing.JsonFuzzing(options);
  139. var data = fuzzing.newArray();
  140. var dataString = goog.json.serialize(data);
  141. print(dataString);
  142. for (var j = 1; j < dataString.length; j++) {
  143. var parser = new goog.net.streams.JsonStreamParser();
  144. var result = [];
  145. var string1 = dataString.substring(0, j);
  146. var parsed = parser.parse(string1);
  147. if (parsed) {
  148. result = goog.array.concat(result, parsed);
  149. }
  150. var string2 = dataString.substring(j);
  151. parsed = parser.parse(string2);
  152. if (parsed) {
  153. result = goog.array.concat(result, parsed);
  154. }
  155. assertEquals(data.length, result.length);
  156. goog.array.forEach(data, function(elm, index) {
  157. assertObjectEquals(dataString, elm, result[index]);
  158. });
  159. }
  160. }
  161. /**
  162. * Parse a fuzzy json string in randomly generated chunks.
  163. */
  164. function testRandomlyChunkedFuzzyMessages() {
  165. var fuzzing = new goog.labs.testing.JsonFuzzing();
  166. var data = fuzzing.newArray();
  167. var dataString = goog.json.serialize(data);
  168. var parser = new goog.net.streams.JsonStreamParser();
  169. var result = [];
  170. print(dataString);
  171. // randomly generated chunks
  172. var pos = 0;
  173. while (pos < dataString.length) {
  174. var num = fuzzing.nextInt(1, dataString.length - pos);
  175. var next = pos + num;
  176. var subString = dataString.substring(pos, next);
  177. print(subString);
  178. pos = next;
  179. var parsed = parser.parse(subString);
  180. if (parsed) {
  181. result = goog.array.concat(result, parsed);
  182. }
  183. }
  184. assertEquals(data.length, result.length);
  185. goog.array.forEach(data, function(elm, index) {
  186. assertObjectEquals(dataString + '\n@' + index, elm, result[index]);
  187. });
  188. }
  189. // TODO(user): add a fuzzy test for this.
  190. function testGetExtraInput() {
  191. var parser = new goog.net.streams.JsonStreamParser();
  192. var result = parser.parse('[] , [[1, 2, 3]]');
  193. assertNull(result);
  194. assertTrue(parser.done());
  195. assertEquals(' , [[1, 2, 3]]', parser.getExtraInput());
  196. parser = new goog.net.streams.JsonStreamParser();
  197. assertFalse(parser.done());
  198. parser.parse(' [{"a" : "b"}, {"c" : "d" ');
  199. assertFalse(parser.done());
  200. parser.parse(' } ] a ');
  201. assertTrue(parser.done());
  202. assertEquals(' a ', parser.getExtraInput());
  203. }
  204. function testDeliverMessageAsRawString() {
  205. var parser = new goog.net.streams.JsonStreamParser(
  206. {'deliverMessageAsRawString': true});
  207. var result = parser.parse(' [{"a" : "b"}, {"c" : "d"},[],{}] ');
  208. assertEquals(4, result.length);
  209. assertEquals('{"a" : "b"}', result[0]);
  210. assertEquals(' {"c" : "d"}', result[1]);
  211. assertEquals('[]', result[2]);
  212. assertEquals('{}', result[3]);
  213. }
  214. function testCompactJsonArrayFormat() {
  215. var message1 = '{"a" : [1, ,2]}';
  216. var message2 = '[, 1,2,, ,null, ,,"abc"]';
  217. var message3 = '[ , ]';
  218. var stream = '[' + message1 + ',' + message2 + ',' + message3 + ']';
  219. var parser = new goog.net.streams.JsonStreamParser(
  220. {'allowCompactJsonArrayFormat': true});
  221. result = parser.parse(stream);
  222. // clang-format off
  223. assertEquals(3, result.length);
  224. assertElementsEquals([1, , 2], result[0].a);
  225. assertElementsEquals([, 1, 2, , , null, , , 'abc'], result[1]);
  226. assertElementsEquals([ , ], result[2]);
  227. // clang-format on
  228. // Raw message strings
  229. parser = new goog.net.streams.JsonStreamParser(
  230. {'allowCompactJsonArrayFormat': true, 'deliverMessageAsRawString': true});
  231. result = parser.parse(stream);
  232. assertEquals(3, result.length);
  233. assertEquals(message1, result[0]);
  234. assertEquals(message2, result[1]);
  235. assertEquals(message3, result[2]);
  236. }