xhrnodereadablestream_test.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  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.XhrNodeReadableStreamTest');
  15. goog.setTestOnly('goog.net.streams.XhrNodeReadableStreamTest');
  16. goog.require('goog.net.streams.NodeReadableStream');
  17. goog.require('goog.net.streams.XhrNodeReadableStream');
  18. goog.require('goog.net.streams.XhrStreamReader');
  19. goog.require('goog.testing.PropertyReplacer');
  20. goog.require('goog.testing.asserts');
  21. goog.require('goog.testing.jsunit');
  22. var xhrReader;
  23. var xhrStream;
  24. var EventType = goog.net.streams.NodeReadableStream.EventType;
  25. var Status = goog.net.streams.XhrStreamReader.Status;
  26. var propertyReplacer;
  27. /**
  28. * Constructs a duck-type XhrStreamReader to simulate xhr events.
  29. * @constructor
  30. * @struct
  31. * @final
  32. */
  33. function MockXhrStreamReader() {
  34. // mocked API
  35. this.setStatusHandler = function(handler) { this.statusHandler_ = handler; };
  36. this.setDataHandler = function(handler) { this.dataHandler_ = handler; };
  37. this.getStatus = function() { return this.status_; };
  38. // simulated events
  39. this.onData = function(messages) { this.dataHandler_(messages); };
  40. this.onStatus = function(status) {
  41. this.status_ = status;
  42. this.statusHandler_();
  43. };
  44. }
  45. function setUp() {
  46. xhrReader = new MockXhrStreamReader();
  47. xhrStream = new goog.net.streams.XhrNodeReadableStream(xhrReader);
  48. propertyReplacer = new goog.testing.PropertyReplacer();
  49. propertyReplacer.replace(xhrStream, 'handleError_', function(message) {
  50. // the real XhrNodeReadableStream class ignores any error thrown
  51. // from inside a callback function, but we want to see those assert
  52. // errors thrown by the test callback function installed by unit tests
  53. fail(message);
  54. });
  55. }
  56. function tearDown() {
  57. propertyReplacer.reset();
  58. }
  59. function testOneDataCallback() {
  60. var delivered = false;
  61. var callback = function(message) {
  62. delivered = true;
  63. assertEquals('a', message.a);
  64. };
  65. xhrStream.on(EventType.DATA, callback);
  66. xhrReader.onData([{a: 'a'}]);
  67. assertTrue(delivered);
  68. }
  69. function testMultipleDataCallbacks() {
  70. var delivered = 0;
  71. var callback = function(message) {
  72. delivered++;
  73. assertEquals('a', message.a);
  74. };
  75. xhrStream.on(EventType.DATA, callback);
  76. xhrStream.on(EventType.DATA, callback);
  77. xhrReader.onData([{a: 'a'}]);
  78. assertEquals(2, delivered);
  79. }
  80. function testOrderedDataCallbacks() {
  81. var delivered = 0;
  82. var callback1 = function(message) {
  83. assertEquals(0, delivered++);
  84. assertEquals('a', message.a);
  85. };
  86. var callback2 = function(message) {
  87. assertEquals(1, delivered++);
  88. assertEquals('a', message.a);
  89. };
  90. xhrStream.on(EventType.DATA, callback1);
  91. xhrStream.on(EventType.DATA, callback2);
  92. xhrReader.onData([{a: 'a'}]);
  93. assertEquals(2, delivered);
  94. }
  95. function testMultipleMessagesCallbacks() {
  96. var delivered = 0;
  97. var callback1 = function(message) {
  98. if (message.a) {
  99. assertEquals(0, delivered++);
  100. assertEquals('a', message.a);
  101. } else if (message.b) {
  102. assertEquals(2, delivered++);
  103. assertEquals('b', message.b);
  104. } else {
  105. fail('unexpected message');
  106. }
  107. };
  108. var callback2 = function(message) {
  109. if (message.a) {
  110. assertEquals(1, delivered++);
  111. assertEquals('a', message.a);
  112. } else if (message.b) {
  113. assertEquals(3, delivered++);
  114. assertEquals('b', message.b);
  115. } else {
  116. fail('unexpected message');
  117. }
  118. };
  119. xhrStream.on(EventType.DATA, callback1);
  120. xhrStream.on(EventType.DATA, callback2);
  121. xhrReader.onData([{a: 'a'}, {b: 'b'}]);
  122. assertEquals(4, delivered);
  123. }
  124. function testMultipleMessagesWithOnceCallbacks() {
  125. var delivered = 0;
  126. var callback1 = function(message) {
  127. if (message.a) {
  128. assertEquals(0, delivered++);
  129. assertEquals('a', message.a);
  130. } else if (message.b) {
  131. assertEquals(1, delivered++);
  132. assertEquals('b', message.b);
  133. } else if (message.c) {
  134. assertEquals(4, delivered++);
  135. assertEquals('c', message.c);
  136. } else {
  137. fail('unexpected message');
  138. }
  139. };
  140. var callback2 = function(message) {
  141. if (message.a) {
  142. assertEquals(2, delivered++);
  143. assertEquals('a', message.a);
  144. } else if (message.b) {
  145. assertEquals(3, delivered++);
  146. assertEquals('b', message.b);
  147. } else {
  148. fail('unexpected message');
  149. }
  150. };
  151. xhrStream.on(EventType.DATA, callback1);
  152. xhrStream.once(EventType.DATA, callback2);
  153. xhrReader.onData([{a: 'a'}, {b: 'b'}]);
  154. assertEquals(4, delivered);
  155. xhrReader.onData([{c: 'c'}]);
  156. assertEquals(5, delivered);
  157. }
  158. function testMultipleMessagesWithRemovedCallbacks() {
  159. var delivered = 0;
  160. var callback1 = function(message) {
  161. if (message.a) {
  162. assertEquals(0, delivered++);
  163. assertEquals('a', message.a);
  164. } else if (message.c) {
  165. assertEquals(3, delivered++);
  166. assertEquals('c', message.c);
  167. } else {
  168. fail('unexpected message');
  169. }
  170. };
  171. var callback2 = function(message) {
  172. if (message.a) {
  173. assertEquals(1, delivered++);
  174. assertEquals('a', message.a);
  175. } else if (message.b) {
  176. assertEquals(2, delivered++);
  177. assertEquals('b', message.b);
  178. } else {
  179. fail('unexpected message');
  180. }
  181. };
  182. xhrStream.on(EventType.DATA, callback1);
  183. xhrStream.once(EventType.DATA, callback2);
  184. xhrReader.onData([{a: 'a'}]);
  185. assertEquals(2, delivered);
  186. xhrStream.removeListener(EventType.DATA, callback1);
  187. xhrStream.once(EventType.DATA, callback2);
  188. xhrReader.onData([{b: 'b'}]);
  189. assertEquals(3, delivered);
  190. xhrStream.on(EventType.DATA, callback1);
  191. xhrStream.once(EventType.DATA, callback2);
  192. xhrStream.removeListener(EventType.DATA, callback2);
  193. xhrReader.onData([{c: 'c'}]);
  194. assertEquals(4, delivered);
  195. xhrStream.removeListener(EventType.DATA, callback1);
  196. xhrReader.onData([{d: 'd'}]);
  197. assertEquals(4, delivered);
  198. }
  199. function testOrderedStatusCallbacks() {
  200. checkStatusMapping(Status.ACTIVE, EventType.READABLE);
  201. checkStatusMapping(Status.BAD_DATA, EventType.ERROR);
  202. checkStatusMapping(Status.HANDLER_EXCEPTION, EventType.ERROR);
  203. checkStatusMapping(Status.NO_DATA, EventType.ERROR);
  204. checkStatusMapping(Status.TIMEOUT, EventType.ERROR);
  205. checkStatusMapping(Status.XHR_ERROR, EventType.ERROR);
  206. checkStatusMapping(Status.CANCELLED, EventType.CLOSE);
  207. checkStatusMapping(Status.SUCCESS, EventType.END);
  208. function checkStatusMapping(status, event) {
  209. var delivered = 0;
  210. var callback1 = function() {
  211. if (delivered == 0) {
  212. delivered++;
  213. } else if (delivered == 2) {
  214. delivered++;
  215. } else {
  216. fail('unexpected status change');
  217. }
  218. assertEquals(status, xhrReader.getStatus());
  219. };
  220. var callback2 = function() {
  221. assertEquals(1, delivered++);
  222. assertEquals(status, xhrReader.getStatus());
  223. };
  224. xhrStream.on(event, callback1);
  225. xhrStream.once(event, callback2);
  226. xhrReader.onStatus(status);
  227. assertEquals(2, delivered);
  228. xhrReader.onStatus(status);
  229. assertEquals(3, delivered);
  230. xhrStream.removeListener(event, callback1);
  231. xhrReader.onStatus(status);
  232. assertEquals(3, delivered);
  233. }
  234. }
  235. function testOrderedStatusMultipleCallbacks() {
  236. checkStatusMapping(Status.ACTIVE, EventType.READABLE);
  237. function checkStatusMapping(status, event) {
  238. var delivered = 0;
  239. var callback1 = function() {
  240. if (delivered == 0) {
  241. delivered++;
  242. } else if (delivered == 2) {
  243. delivered++;
  244. } else if (delivered == 4) {
  245. delivered++;
  246. } else {
  247. fail('unexpected status change');
  248. }
  249. assertEquals(status, xhrReader.getStatus());
  250. };
  251. var callback2 = function() {
  252. if (delivered == 1) {
  253. delivered++;
  254. } else if (delivered == 3) {
  255. delivered++;
  256. } else if (delivered == 5) {
  257. delivered++;
  258. } else if (delivered == 6) {
  259. delivered++;
  260. } else {
  261. fail('unexpected status change');
  262. }
  263. assertEquals(status, xhrReader.getStatus());
  264. };
  265. xhrStream.on(event, callback1);
  266. xhrStream.on(event, callback2);
  267. xhrStream.once(event, callback1);
  268. xhrStream.once(event, callback2);
  269. xhrReader.onStatus(status);
  270. assertEquals(4, delivered);
  271. xhrReader.onStatus(status);
  272. assertEquals(6, delivered);
  273. xhrStream.removeListener(event, callback1);
  274. xhrReader.onStatus(status);
  275. assertEquals(7, delivered);
  276. }
  277. }