simpleresult_test.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. // Copyright 2012 The Closure Library Authors. All Rights Reserved.
  2. // Use of this source code is governed by the Apache License, Version 2.0.
  3. goog.provide('goog.result.SimpleResultTest');
  4. goog.setTestOnly('goog.result.SimpleResultTest');
  5. goog.require('goog.Timer');
  6. goog.require('goog.Promise');
  7. goog.require('goog.Thenable');
  8. goog.require('goog.result');
  9. goog.require('goog.testing.MockClock');
  10. goog.require('goog.testing.recordFunction');
  11. goog.require('goog.testing.jsunit');
  12. var result, mockClock, resultCallback;
  13. var resultCallback1;
  14. var resultCallback2;
  15. function setUpPage() {
  16. mockClock = new goog.testing.MockClock();
  17. mockClock.install();
  18. }
  19. function setUp() {
  20. mockClock.reset();
  21. resultCallback = new goog.testing.recordFunction();
  22. resultCallback1 = new goog.testing.recordFunction();
  23. resultCallback2 = new goog.testing.recordFunction();
  24. result = new goog.result.SimpleResult();
  25. }
  26. function tearDown() {
  27. resultCallback = resultCallback1 = resultCallback2 = result = null;
  28. }
  29. function tearDownPage() {
  30. mockClock.uninstall();
  31. goog.dispose(mockClock);
  32. }
  33. function testHandlersCalledOnSuccess() {
  34. result.wait(resultCallback1);
  35. result.wait(resultCallback2);
  36. assertEquals(goog.result.Result.State.PENDING, result.getState());
  37. assertEquals(0, resultCallback1.getCallCount());
  38. assertEquals(0, resultCallback2.getCallCount());
  39. result.setValue(2);
  40. assertEquals(goog.result.Result.State.SUCCESS, result.getState());
  41. assertEquals(2, result.getValue());
  42. assertEquals(1, resultCallback1.getCallCount());
  43. assertEquals(1, resultCallback2.getCallCount());
  44. var res1 = resultCallback1.popLastCall().getArgument(0);
  45. assertObjectEquals(result, res1);
  46. var res2 = resultCallback2.popLastCall().getArgument(0);
  47. assertObjectEquals(result, res2);
  48. }
  49. function testCustomHandlerScope() {
  50. result.wait(resultCallback1);
  51. var scope = {};
  52. result.wait(resultCallback2, scope);
  53. result.setValue(2);
  54. assertEquals(1, resultCallback1.getCallCount());
  55. assertEquals(1, resultCallback2.getCallCount());
  56. var this1 = resultCallback1.popLastCall().getThis();
  57. assertObjectEquals(goog.global, this1);
  58. var this2 = resultCallback2.popLastCall().getThis();
  59. assertObjectEquals(scope, this2);
  60. }
  61. function testHandlersCalledOnError() {
  62. result.wait(resultCallback1);
  63. result.wait(resultCallback2);
  64. assertEquals(goog.result.Result.State.PENDING, result.getState());
  65. var error = "Network Error";
  66. result.setError(error);
  67. assertEquals(goog.result.Result.State.ERROR, result.getState());
  68. assertEquals(error, result.getError());
  69. assertEquals(1, resultCallback1.getCallCount());
  70. assertEquals(1, resultCallback2.getCallCount());
  71. var res1 = resultCallback1.popLastCall().getArgument(0);
  72. assertObjectEquals(result, res1);
  73. var res2 = resultCallback2.popLastCall().getArgument(0);
  74. assertObjectEquals(result, res2);
  75. }
  76. function testAttachingHandlerOnSuccessfulResult() {
  77. result.setValue(2);
  78. assertEquals(goog.result.Result.State.SUCCESS, result.getState());
  79. assertEquals(2, result.getValue());
  80. // resultCallback should be called immediately on a resolved Result
  81. assertEquals(0, resultCallback.getCallCount());
  82. result.wait(resultCallback);
  83. assertEquals(1, resultCallback.getCallCount());
  84. var res = resultCallback.popLastCall().getArgument(0);
  85. assertEquals(result, res);
  86. }
  87. function testAttachingHandlerOnErrorResult() {
  88. var error = { code: -1, errorString: "Invalid JSON" };
  89. result.setError(error);
  90. assertEquals(goog.result.Result.State.ERROR, result.getState());
  91. assertEquals(error, result.getError());
  92. // resultCallback should be called immediately on a resolved Result
  93. assertEquals(0, resultCallback.getCallCount());
  94. result.wait(resultCallback);
  95. assertEquals(1, resultCallback.getCallCount());
  96. var res = resultCallback.popLastCall().getArgument(0);
  97. assertEquals(result, res);
  98. }
  99. function testExceptionThrownOnMultipleSuccessfulResolutionAttempts() {
  100. result.setValue(1);
  101. assertEquals(goog.result.Result.State.SUCCESS, result.getState());
  102. assertEquals(1, result.getValue());
  103. // Try to set the value again
  104. var e = assertThrows(goog.bind(result.setValue, result, 3));
  105. assertTrue(e instanceof goog.result.SimpleResult.StateError);
  106. }
  107. function testExceptionThrownOnMultipleErrorResolutionAttempts() {
  108. assertEquals(goog.result.Result.State.PENDING, result.getState());
  109. result.setError(5);
  110. assertEquals(goog.result.Result.State.ERROR, result.getState());
  111. assertEquals(5, result.getError());
  112. // Try to set error again
  113. var e = assertThrows(goog.bind(result.setError, result, 4));
  114. assertTrue(e instanceof goog.result.SimpleResult.StateError);
  115. }
  116. function testExceptionThrownOnSuccessThenErrorResolutionAttempt() {
  117. assertEquals(goog.result.Result.State.PENDING, result.getState());
  118. result.setValue(1);
  119. assertEquals(goog.result.Result.State.SUCCESS, result.getState());
  120. assertEquals(1, result.getValue());
  121. // Try to set error after setting value
  122. var e = assertThrows(goog.bind(result.setError, result, 3));
  123. assertTrue(e instanceof goog.result.SimpleResult.StateError);
  124. }
  125. function testExceptionThrownOnErrorThenSuccessResolutionAttempt() {
  126. assertEquals(goog.result.Result.State.PENDING, result.getState());
  127. var error = "fail";
  128. result.setError(error);
  129. assertEquals(goog.result.Result.State.ERROR, result.getState());
  130. assertEquals(error, result.getError());
  131. // Try to set value after setting error
  132. var e = assertThrows(goog.bind(result.setValue, result, 1));
  133. assertTrue(e instanceof goog.result.SimpleResult.StateError);
  134. }
  135. function testSuccessfulAsyncResolution() {
  136. result.wait(resultCallback);
  137. assertEquals(goog.result.Result.State.PENDING, result.getState());
  138. goog.Timer.callOnce(function() {
  139. result.setValue(1);
  140. });
  141. mockClock.tick();
  142. assertEquals(1, resultCallback.getCallCount());
  143. var res = resultCallback.popLastCall().getArgument(0);
  144. assertEquals(goog.result.Result.State.SUCCESS, res.getState());
  145. assertEquals(1, res.getValue());
  146. }
  147. function testErrorAsyncResolution() {
  148. result.wait(resultCallback);
  149. assertEquals(goog.result.Result.State.PENDING, result.getState());
  150. var error = 'Network failure';
  151. goog.Timer.callOnce(function() {
  152. result.setError(error);
  153. });
  154. mockClock.tick();
  155. assertEquals(1, resultCallback.getCallCount());
  156. var res = resultCallback.popLastCall().getArgument(0);
  157. assertEquals(goog.result.Result.State.ERROR, res.getState());
  158. assertEquals(error, res.getError());
  159. }
  160. function testCancelStateAndReturn() {
  161. assertFalse(result.isCanceled());
  162. var canceled = result.cancel();
  163. assertTrue(result.isCanceled());
  164. assertEquals(goog.result.Result.State.ERROR, result.getState());
  165. assertTrue(result.getError() instanceof goog.result.Result.CancelError);
  166. assertTrue(canceled);
  167. }
  168. function testErrorHandlersFireOnCancel() {
  169. result.wait(resultCallback);
  170. result.cancel();
  171. assertEquals(1, resultCallback.getCallCount());
  172. var lastCall = resultCallback.popLastCall();
  173. var res = lastCall.getArgument(0);
  174. assertEquals(goog.result.Result.State.ERROR, res.getState());
  175. assertTrue(res.getError() instanceof goog.result.Result.CancelError);
  176. }
  177. function testCancelAfterSetValue() {
  178. // cancel after setValue/setError => no-op
  179. result.wait(resultCallback);
  180. result.setValue(1);
  181. assertEquals(goog.result.Result.State.SUCCESS, result.getState());
  182. assertEquals(1, result.getValue());
  183. assertEquals(1, resultCallback.getCallCount());
  184. result.cancel();
  185. assertEquals(goog.result.Result.State.SUCCESS, result.getState());
  186. assertEquals(1, result.getValue());
  187. assertEquals(1, resultCallback.getCallCount());
  188. }
  189. function testSetValueAfterCancel() {
  190. // setValue/setError after cancel => no-op
  191. result.wait(resultCallback);
  192. result.cancel();
  193. assertTrue(result.isCanceled());
  194. assertTrue(result.getError() instanceof goog.result.Result.CancelError);
  195. result.setValue(1);
  196. assertTrue(result.isCanceled());
  197. assertTrue(result.getError() instanceof goog.result.Result.CancelError);
  198. result.setError(3);
  199. assertTrue(result.isCanceled());
  200. assertTrue(result.getError() instanceof goog.result.Result.CancelError);
  201. }
  202. function testFromResolvedPromise() {
  203. var promise = goog.Promise.resolve('resolved');
  204. result = goog.result.SimpleResult.fromPromise(promise);
  205. assertEquals(goog.result.Result.State.PENDING, result.getState());
  206. mockClock.tick();
  207. assertEquals(goog.result.Result.State.SUCCESS, result.getState());
  208. assertEquals('resolved', result.getValue());
  209. assertEquals(undefined, result.getError());
  210. }
  211. function testFromRejectedPromise() {
  212. var promise = goog.Promise.reject('rejected');
  213. result = goog.result.SimpleResult.fromPromise(promise);
  214. assertEquals(goog.result.Result.State.PENDING, result.getState());
  215. mockClock.tick();
  216. assertEquals(goog.result.Result.State.ERROR, result.getState());
  217. assertEquals(undefined, result.getValue());
  218. assertEquals('rejected', result.getError());
  219. }
  220. function testThen() {
  221. var value1, value2;
  222. result.then(function(val1) {
  223. return value1 = val1;
  224. }).then(function(val2) {
  225. value2 = val2;
  226. });
  227. result.setValue('done');
  228. assertUndefined(value1);
  229. assertUndefined(value2);
  230. mockClock.tick();
  231. assertEquals('done', value1);
  232. assertEquals('done', value2);
  233. }
  234. function testThen_reject() {
  235. var value, reason;
  236. result.then(
  237. function(v) { value = v; },
  238. function(r) { reason = r; });
  239. result.setError(new Error('oops'));
  240. assertUndefined(value);
  241. mockClock.tick();
  242. assertUndefined(value);
  243. assertEquals('oops', reason.message);
  244. }
  245. function testPromiseAll() {
  246. var promise = goog.Promise.resolve('promise');
  247. goog.Promise.all([result, promise]).then(function(values) {
  248. assertEquals(2, values.length);
  249. assertEquals('result', values[0]);
  250. assertEquals('promise', values[1]);
  251. });
  252. result.setValue('result');
  253. mockClock.tick();
  254. }
  255. function testResolvingPromiseBlocksResult() {
  256. var value;
  257. goog.Promise.resolve('promise').then(function(value) {
  258. result.setValue(value);
  259. });
  260. result.wait(function(r) {
  261. value = r.getValue();
  262. });
  263. assertUndefined(value);
  264. mockClock.tick();
  265. assertEquals('promise', value);
  266. }
  267. function testRejectingPromiseBlocksResult() {
  268. var err;
  269. goog.Promise.reject(new Error('oops')).then(
  270. undefined /* opt_onResolved */,
  271. function(reason) {
  272. result.setError(reason);
  273. });
  274. result.wait(function(r) {
  275. err = r.getError();
  276. });
  277. assertUndefined(err);
  278. mockClock.tick();
  279. assertEquals('oops', err.message);
  280. }
  281. function testPromiseFromCanceledResult() {
  282. var reason;
  283. result.cancel();
  284. result.then(
  285. undefined /* opt_onResolved */,
  286. function(r) {
  287. reason = r;
  288. });
  289. mockClock.tick();
  290. assertTrue(reason instanceof goog.Promise.CancellationError);
  291. }
  292. function testThenableInterface() {
  293. assertTrue(goog.Thenable.isImplementedBy(result));
  294. }