a zip code crypto-currency system good for red ONLY

fake-async-test.js 29KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. /**
  2. * @license
  3. * Copyright Google Inc. All Rights Reserved.
  4. *
  5. * Use of this source code is governed by an MIT-style license that can be
  6. * found in the LICENSE file at https://angular.io/license
  7. */
  8. (function (global, factory) {
  9. typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
  10. typeof define === 'function' && define.amd ? define(factory) :
  11. (factory());
  12. }(this, (function () { 'use strict';
  13. /**
  14. * @license
  15. * Copyright Google Inc. All Rights Reserved.
  16. *
  17. * Use of this source code is governed by an MIT-style license that can be
  18. * found in the LICENSE file at https://angular.io/license
  19. */
  20. var __read = (undefined && undefined.__read) || function (o, n) {
  21. var m = typeof Symbol === "function" && o[Symbol.iterator];
  22. if (!m) return o;
  23. var i = m.call(o), r, ar = [], e;
  24. try {
  25. while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
  26. }
  27. catch (error) { e = { error: error }; }
  28. finally {
  29. try {
  30. if (r && !r.done && (m = i["return"])) m.call(i);
  31. }
  32. finally { if (e) throw e.error; }
  33. }
  34. return ar;
  35. };
  36. var __spread = (undefined && undefined.__spread) || function () {
  37. for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
  38. return ar;
  39. };
  40. (function (global) {
  41. var OriginalDate = global.Date;
  42. var FakeDate = /** @class */ (function () {
  43. function FakeDate() {
  44. if (arguments.length === 0) {
  45. var d = new OriginalDate();
  46. d.setTime(FakeDate.now());
  47. return d;
  48. }
  49. else {
  50. var args = Array.prototype.slice.call(arguments);
  51. return new (OriginalDate.bind.apply(OriginalDate, __spread([void 0], args)))();
  52. }
  53. }
  54. FakeDate.now = function () {
  55. var fakeAsyncTestZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
  56. if (fakeAsyncTestZoneSpec) {
  57. return fakeAsyncTestZoneSpec.getCurrentRealTime() + fakeAsyncTestZoneSpec.getCurrentTime();
  58. }
  59. return OriginalDate.now.apply(this, arguments);
  60. };
  61. return FakeDate;
  62. }());
  63. FakeDate.UTC = OriginalDate.UTC;
  64. FakeDate.parse = OriginalDate.parse;
  65. // keep a reference for zone patched timer function
  66. var timers = {
  67. setTimeout: global.setTimeout,
  68. setInterval: global.setInterval,
  69. clearTimeout: global.clearTimeout,
  70. clearInterval: global.clearInterval
  71. };
  72. var Scheduler = /** @class */ (function () {
  73. function Scheduler() {
  74. // Next scheduler id.
  75. this.nextId = 1;
  76. // Scheduler queue with the tuple of end time and callback function - sorted by end time.
  77. this._schedulerQueue = [];
  78. // Current simulated time in millis.
  79. this._currentTime = 0;
  80. // Current real time in millis.
  81. this._currentRealTime = OriginalDate.now();
  82. }
  83. Scheduler.prototype.getCurrentTime = function () {
  84. return this._currentTime;
  85. };
  86. Scheduler.prototype.getCurrentRealTime = function () {
  87. return this._currentRealTime;
  88. };
  89. Scheduler.prototype.setCurrentRealTime = function (realTime) {
  90. this._currentRealTime = realTime;
  91. };
  92. Scheduler.prototype.scheduleFunction = function (cb, delay, args, isPeriodic, isRequestAnimationFrame, id) {
  93. if (args === void 0) { args = []; }
  94. if (isPeriodic === void 0) { isPeriodic = false; }
  95. if (isRequestAnimationFrame === void 0) { isRequestAnimationFrame = false; }
  96. if (id === void 0) { id = -1; }
  97. var currentId = id < 0 ? this.nextId++ : id;
  98. var endTime = this._currentTime + delay;
  99. // Insert so that scheduler queue remains sorted by end time.
  100. var newEntry = {
  101. endTime: endTime,
  102. id: currentId,
  103. func: cb,
  104. args: args,
  105. delay: delay,
  106. isPeriodic: isPeriodic,
  107. isRequestAnimationFrame: isRequestAnimationFrame
  108. };
  109. var i = 0;
  110. for (; i < this._schedulerQueue.length; i++) {
  111. var currentEntry = this._schedulerQueue[i];
  112. if (newEntry.endTime < currentEntry.endTime) {
  113. break;
  114. }
  115. }
  116. this._schedulerQueue.splice(i, 0, newEntry);
  117. return currentId;
  118. };
  119. Scheduler.prototype.removeScheduledFunctionWithId = function (id) {
  120. for (var i = 0; i < this._schedulerQueue.length; i++) {
  121. if (this._schedulerQueue[i].id == id) {
  122. this._schedulerQueue.splice(i, 1);
  123. break;
  124. }
  125. }
  126. };
  127. Scheduler.prototype.tick = function (millis, doTick) {
  128. if (millis === void 0) { millis = 0; }
  129. var finalTime = this._currentTime + millis;
  130. var lastCurrentTime = 0;
  131. if (this._schedulerQueue.length === 0 && doTick) {
  132. doTick(millis);
  133. return;
  134. }
  135. while (this._schedulerQueue.length > 0) {
  136. var current = this._schedulerQueue[0];
  137. if (finalTime < current.endTime) {
  138. // Done processing the queue since it's sorted by endTime.
  139. break;
  140. }
  141. else {
  142. // Time to run scheduled function. Remove it from the head of queue.
  143. var current_1 = this._schedulerQueue.shift();
  144. lastCurrentTime = this._currentTime;
  145. this._currentTime = current_1.endTime;
  146. if (doTick) {
  147. doTick(this._currentTime - lastCurrentTime);
  148. }
  149. var retval = current_1.func.apply(global, current_1.args);
  150. if (!retval) {
  151. // Uncaught exception in the current scheduled function. Stop processing the queue.
  152. break;
  153. }
  154. }
  155. }
  156. this._currentTime = finalTime;
  157. };
  158. Scheduler.prototype.flush = function (limit, flushPeriodic, doTick) {
  159. if (limit === void 0) { limit = 20; }
  160. if (flushPeriodic === void 0) { flushPeriodic = false; }
  161. if (flushPeriodic) {
  162. return this.flushPeriodic(doTick);
  163. }
  164. else {
  165. return this.flushNonPeriodic(limit, doTick);
  166. }
  167. };
  168. Scheduler.prototype.flushPeriodic = function (doTick) {
  169. if (this._schedulerQueue.length === 0) {
  170. return 0;
  171. }
  172. // Find the last task currently queued in the scheduler queue and tick
  173. // till that time.
  174. var startTime = this._currentTime;
  175. var lastTask = this._schedulerQueue[this._schedulerQueue.length - 1];
  176. this.tick(lastTask.endTime - startTime, doTick);
  177. return this._currentTime - startTime;
  178. };
  179. Scheduler.prototype.flushNonPeriodic = function (limit, doTick) {
  180. var startTime = this._currentTime;
  181. var lastCurrentTime = 0;
  182. var count = 0;
  183. while (this._schedulerQueue.length > 0) {
  184. count++;
  185. if (count > limit) {
  186. throw new Error('flush failed after reaching the limit of ' + limit +
  187. ' tasks. Does your code use a polling timeout?');
  188. }
  189. // flush only non-periodic timers.
  190. // If the only remaining tasks are periodic(or requestAnimationFrame), finish flushing.
  191. if (this._schedulerQueue.filter(function (task) { return !task.isPeriodic && !task.isRequestAnimationFrame; })
  192. .length === 0) {
  193. break;
  194. }
  195. var current = this._schedulerQueue.shift();
  196. lastCurrentTime = this._currentTime;
  197. this._currentTime = current.endTime;
  198. if (doTick) {
  199. // Update any secondary schedulers like Jasmine mock Date.
  200. doTick(this._currentTime - lastCurrentTime);
  201. }
  202. var retval = current.func.apply(global, current.args);
  203. if (!retval) {
  204. // Uncaught exception in the current scheduled function. Stop processing the queue.
  205. break;
  206. }
  207. }
  208. return this._currentTime - startTime;
  209. };
  210. return Scheduler;
  211. }());
  212. var FakeAsyncTestZoneSpec = /** @class */ (function () {
  213. function FakeAsyncTestZoneSpec(namePrefix, trackPendingRequestAnimationFrame, macroTaskOptions) {
  214. if (trackPendingRequestAnimationFrame === void 0) { trackPendingRequestAnimationFrame = false; }
  215. this.trackPendingRequestAnimationFrame = trackPendingRequestAnimationFrame;
  216. this.macroTaskOptions = macroTaskOptions;
  217. this._scheduler = new Scheduler();
  218. this._microtasks = [];
  219. this._lastError = null;
  220. this._uncaughtPromiseErrors = Promise[Zone.__symbol__('uncaughtPromiseErrors')];
  221. this.pendingPeriodicTimers = [];
  222. this.pendingTimers = [];
  223. this.patchDateLocked = false;
  224. this.properties = { 'FakeAsyncTestZoneSpec': this };
  225. this.name = 'fakeAsyncTestZone for ' + namePrefix;
  226. // in case user can't access the construction of FakeAsyncTestSpec
  227. // user can also define macroTaskOptions by define a global variable.
  228. if (!this.macroTaskOptions) {
  229. this.macroTaskOptions = global[Zone.__symbol__('FakeAsyncTestMacroTask')];
  230. }
  231. }
  232. FakeAsyncTestZoneSpec.assertInZone = function () {
  233. if (Zone.current.get('FakeAsyncTestZoneSpec') == null) {
  234. throw new Error('The code should be running in the fakeAsync zone to call this function');
  235. }
  236. };
  237. FakeAsyncTestZoneSpec.prototype._fnAndFlush = function (fn, completers) {
  238. var _this = this;
  239. return function () {
  240. var args = [];
  241. for (var _i = 0; _i < arguments.length; _i++) {
  242. args[_i] = arguments[_i];
  243. }
  244. fn.apply(global, args);
  245. if (_this._lastError === null) {
  246. if (completers.onSuccess != null) {
  247. completers.onSuccess.apply(global);
  248. }
  249. // Flush microtasks only on success.
  250. _this.flushMicrotasks();
  251. }
  252. else {
  253. if (completers.onError != null) {
  254. completers.onError.apply(global);
  255. }
  256. }
  257. // Return true if there were no errors, false otherwise.
  258. return _this._lastError === null;
  259. };
  260. };
  261. FakeAsyncTestZoneSpec._removeTimer = function (timers, id) {
  262. var index = timers.indexOf(id);
  263. if (index > -1) {
  264. timers.splice(index, 1);
  265. }
  266. };
  267. FakeAsyncTestZoneSpec.prototype._dequeueTimer = function (id) {
  268. var _this = this;
  269. return function () {
  270. FakeAsyncTestZoneSpec._removeTimer(_this.pendingTimers, id);
  271. };
  272. };
  273. FakeAsyncTestZoneSpec.prototype._requeuePeriodicTimer = function (fn, interval, args, id) {
  274. var _this = this;
  275. return function () {
  276. // Requeue the timer callback if it's not been canceled.
  277. if (_this.pendingPeriodicTimers.indexOf(id) !== -1) {
  278. _this._scheduler.scheduleFunction(fn, interval, args, true, false, id);
  279. }
  280. };
  281. };
  282. FakeAsyncTestZoneSpec.prototype._dequeuePeriodicTimer = function (id) {
  283. var _this = this;
  284. return function () {
  285. FakeAsyncTestZoneSpec._removeTimer(_this.pendingPeriodicTimers, id);
  286. };
  287. };
  288. FakeAsyncTestZoneSpec.prototype._setTimeout = function (fn, delay, args, isTimer) {
  289. if (isTimer === void 0) { isTimer = true; }
  290. var removeTimerFn = this._dequeueTimer(this._scheduler.nextId);
  291. // Queue the callback and dequeue the timer on success and error.
  292. var cb = this._fnAndFlush(fn, { onSuccess: removeTimerFn, onError: removeTimerFn });
  293. var id = this._scheduler.scheduleFunction(cb, delay, args, false, !isTimer);
  294. if (isTimer) {
  295. this.pendingTimers.push(id);
  296. }
  297. return id;
  298. };
  299. FakeAsyncTestZoneSpec.prototype._clearTimeout = function (id) {
  300. FakeAsyncTestZoneSpec._removeTimer(this.pendingTimers, id);
  301. this._scheduler.removeScheduledFunctionWithId(id);
  302. };
  303. FakeAsyncTestZoneSpec.prototype._setInterval = function (fn, interval, args) {
  304. var id = this._scheduler.nextId;
  305. var completers = { onSuccess: null, onError: this._dequeuePeriodicTimer(id) };
  306. var cb = this._fnAndFlush(fn, completers);
  307. // Use the callback created above to requeue on success.
  308. completers.onSuccess = this._requeuePeriodicTimer(cb, interval, args, id);
  309. // Queue the callback and dequeue the periodic timer only on error.
  310. this._scheduler.scheduleFunction(cb, interval, args, true);
  311. this.pendingPeriodicTimers.push(id);
  312. return id;
  313. };
  314. FakeAsyncTestZoneSpec.prototype._clearInterval = function (id) {
  315. FakeAsyncTestZoneSpec._removeTimer(this.pendingPeriodicTimers, id);
  316. this._scheduler.removeScheduledFunctionWithId(id);
  317. };
  318. FakeAsyncTestZoneSpec.prototype._resetLastErrorAndThrow = function () {
  319. var error = this._lastError || this._uncaughtPromiseErrors[0];
  320. this._uncaughtPromiseErrors.length = 0;
  321. this._lastError = null;
  322. throw error;
  323. };
  324. FakeAsyncTestZoneSpec.prototype.getCurrentTime = function () {
  325. return this._scheduler.getCurrentTime();
  326. };
  327. FakeAsyncTestZoneSpec.prototype.getCurrentRealTime = function () {
  328. return this._scheduler.getCurrentRealTime();
  329. };
  330. FakeAsyncTestZoneSpec.prototype.setCurrentRealTime = function (realTime) {
  331. this._scheduler.setCurrentRealTime(realTime);
  332. };
  333. FakeAsyncTestZoneSpec.patchDate = function () {
  334. if (global['Date'] === FakeDate) {
  335. // already patched
  336. return;
  337. }
  338. global['Date'] = FakeDate;
  339. FakeDate.prototype = OriginalDate.prototype;
  340. // try check and reset timers
  341. // because jasmine.clock().install() may
  342. // have replaced the global timer
  343. FakeAsyncTestZoneSpec.checkTimerPatch();
  344. };
  345. FakeAsyncTestZoneSpec.resetDate = function () {
  346. if (global['Date'] === FakeDate) {
  347. global['Date'] = OriginalDate;
  348. }
  349. };
  350. FakeAsyncTestZoneSpec.checkTimerPatch = function () {
  351. if (global.setTimeout !== timers.setTimeout) {
  352. global.setTimeout = timers.setTimeout;
  353. global.clearTimeout = timers.clearTimeout;
  354. }
  355. if (global.setInterval !== timers.setInterval) {
  356. global.setInterval = timers.setInterval;
  357. global.clearInterval = timers.clearInterval;
  358. }
  359. };
  360. FakeAsyncTestZoneSpec.prototype.lockDatePatch = function () {
  361. this.patchDateLocked = true;
  362. FakeAsyncTestZoneSpec.patchDate();
  363. };
  364. FakeAsyncTestZoneSpec.prototype.unlockDatePatch = function () {
  365. this.patchDateLocked = false;
  366. FakeAsyncTestZoneSpec.resetDate();
  367. };
  368. FakeAsyncTestZoneSpec.prototype.tick = function (millis, doTick) {
  369. if (millis === void 0) { millis = 0; }
  370. FakeAsyncTestZoneSpec.assertInZone();
  371. this.flushMicrotasks();
  372. this._scheduler.tick(millis, doTick);
  373. if (this._lastError !== null) {
  374. this._resetLastErrorAndThrow();
  375. }
  376. };
  377. FakeAsyncTestZoneSpec.prototype.flushMicrotasks = function () {
  378. var _this = this;
  379. FakeAsyncTestZoneSpec.assertInZone();
  380. var flushErrors = function () {
  381. if (_this._lastError !== null || _this._uncaughtPromiseErrors.length) {
  382. // If there is an error stop processing the microtask queue and rethrow the error.
  383. _this._resetLastErrorAndThrow();
  384. }
  385. };
  386. while (this._microtasks.length > 0) {
  387. var microtask = this._microtasks.shift();
  388. microtask.func.apply(microtask.target, microtask.args);
  389. }
  390. flushErrors();
  391. };
  392. FakeAsyncTestZoneSpec.prototype.flush = function (limit, flushPeriodic, doTick) {
  393. FakeAsyncTestZoneSpec.assertInZone();
  394. this.flushMicrotasks();
  395. var elapsed = this._scheduler.flush(limit, flushPeriodic, doTick);
  396. if (this._lastError !== null) {
  397. this._resetLastErrorAndThrow();
  398. }
  399. return elapsed;
  400. };
  401. FakeAsyncTestZoneSpec.prototype.onScheduleTask = function (delegate, current, target, task) {
  402. switch (task.type) {
  403. case 'microTask':
  404. var args = task.data && task.data.args;
  405. // should pass additional arguments to callback if have any
  406. // currently we know process.nextTick will have such additional
  407. // arguments
  408. var additionalArgs = void 0;
  409. if (args) {
  410. var callbackIndex = task.data.cbIdx;
  411. if (typeof args.length === 'number' && args.length > callbackIndex + 1) {
  412. additionalArgs = Array.prototype.slice.call(args, callbackIndex + 1);
  413. }
  414. }
  415. this._microtasks.push({
  416. func: task.invoke,
  417. args: additionalArgs,
  418. target: task.data && task.data.target
  419. });
  420. break;
  421. case 'macroTask':
  422. switch (task.source) {
  423. case 'setTimeout':
  424. task.data['handleId'] = this._setTimeout(task.invoke, task.data['delay'], Array.prototype.slice.call(task.data['args'], 2));
  425. break;
  426. case 'setImmediate':
  427. task.data['handleId'] = this._setTimeout(task.invoke, 0, Array.prototype.slice.call(task.data['args'], 1));
  428. break;
  429. case 'setInterval':
  430. task.data['handleId'] = this._setInterval(task.invoke, task.data['delay'], Array.prototype.slice.call(task.data['args'], 2));
  431. break;
  432. case 'XMLHttpRequest.send':
  433. throw new Error('Cannot make XHRs from within a fake async test. Request URL: ' +
  434. task.data['url']);
  435. case 'requestAnimationFrame':
  436. case 'webkitRequestAnimationFrame':
  437. case 'mozRequestAnimationFrame':
  438. // Simulate a requestAnimationFrame by using a setTimeout with 16 ms.
  439. // (60 frames per second)
  440. task.data['handleId'] = this._setTimeout(task.invoke, 16, task.data['args'], this.trackPendingRequestAnimationFrame);
  441. break;
  442. default:
  443. // user can define which macroTask they want to support by passing
  444. // macroTaskOptions
  445. var macroTaskOption = this.findMacroTaskOption(task);
  446. if (macroTaskOption) {
  447. var args_1 = task.data && task.data['args'];
  448. var delay = args_1 && args_1.length > 1 ? args_1[1] : 0;
  449. var callbackArgs = macroTaskOption.callbackArgs ? macroTaskOption.callbackArgs : args_1;
  450. if (!!macroTaskOption.isPeriodic) {
  451. // periodic macroTask, use setInterval to simulate
  452. task.data['handleId'] = this._setInterval(task.invoke, delay, callbackArgs);
  453. task.data.isPeriodic = true;
  454. }
  455. else {
  456. // not periodic, use setTimeout to simulate
  457. task.data['handleId'] = this._setTimeout(task.invoke, delay, callbackArgs);
  458. }
  459. break;
  460. }
  461. throw new Error('Unknown macroTask scheduled in fake async test: ' + task.source);
  462. }
  463. break;
  464. case 'eventTask':
  465. task = delegate.scheduleTask(target, task);
  466. break;
  467. }
  468. return task;
  469. };
  470. FakeAsyncTestZoneSpec.prototype.onCancelTask = function (delegate, current, target, task) {
  471. switch (task.source) {
  472. case 'setTimeout':
  473. case 'requestAnimationFrame':
  474. case 'webkitRequestAnimationFrame':
  475. case 'mozRequestAnimationFrame':
  476. return this._clearTimeout(task.data['handleId']);
  477. case 'setInterval':
  478. return this._clearInterval(task.data['handleId']);
  479. default:
  480. // user can define which macroTask they want to support by passing
  481. // macroTaskOptions
  482. var macroTaskOption = this.findMacroTaskOption(task);
  483. if (macroTaskOption) {
  484. var handleId = task.data['handleId'];
  485. return macroTaskOption.isPeriodic ? this._clearInterval(handleId) :
  486. this._clearTimeout(handleId);
  487. }
  488. return delegate.cancelTask(target, task);
  489. }
  490. };
  491. FakeAsyncTestZoneSpec.prototype.onInvoke = function (delegate, current, target, callback, applyThis, applyArgs, source) {
  492. try {
  493. FakeAsyncTestZoneSpec.patchDate();
  494. return delegate.invoke(target, callback, applyThis, applyArgs, source);
  495. }
  496. finally {
  497. if (!this.patchDateLocked) {
  498. FakeAsyncTestZoneSpec.resetDate();
  499. }
  500. }
  501. };
  502. FakeAsyncTestZoneSpec.prototype.findMacroTaskOption = function (task) {
  503. if (!this.macroTaskOptions) {
  504. return null;
  505. }
  506. for (var i = 0; i < this.macroTaskOptions.length; i++) {
  507. var macroTaskOption = this.macroTaskOptions[i];
  508. if (macroTaskOption.source === task.source) {
  509. return macroTaskOption;
  510. }
  511. }
  512. return null;
  513. };
  514. FakeAsyncTestZoneSpec.prototype.onHandleError = function (parentZoneDelegate, currentZone, targetZone, error) {
  515. this._lastError = error;
  516. return false; // Don't propagate error to parent zone.
  517. };
  518. return FakeAsyncTestZoneSpec;
  519. }());
  520. // Export the class so that new instances can be created with proper
  521. // constructor params.
  522. Zone['FakeAsyncTestZoneSpec'] = FakeAsyncTestZoneSpec;
  523. })(typeof window === 'object' && window || typeof self === 'object' && self || global);
  524. /**
  525. * @license
  526. * Copyright Google Inc. All Rights Reserved.
  527. *
  528. * Use of this source code is governed by an MIT-style license that can be
  529. * found in the LICENSE file at https://angular.io/license
  530. */
  531. Zone.__load_patch('fakeasync', function (global, Zone, api) {
  532. var FakeAsyncTestZoneSpec = Zone && Zone['FakeAsyncTestZoneSpec'];
  533. var ProxyZoneSpec = Zone && Zone['ProxyZoneSpec'];
  534. var _fakeAsyncTestZoneSpec = null;
  535. /**
  536. * Clears out the shared fake async zone for a test.
  537. * To be called in a global `beforeEach`.
  538. *
  539. * @experimental
  540. */
  541. function resetFakeAsyncZone() {
  542. if (_fakeAsyncTestZoneSpec) {
  543. _fakeAsyncTestZoneSpec.unlockDatePatch();
  544. }
  545. _fakeAsyncTestZoneSpec = null;
  546. // in node.js testing we may not have ProxyZoneSpec in which case there is nothing to reset.
  547. ProxyZoneSpec && ProxyZoneSpec.assertPresent().resetDelegate();
  548. }
  549. /**
  550. * Wraps a function to be executed in the fakeAsync zone:
  551. * - microtasks are manually executed by calling `flushMicrotasks()`,
  552. * - timers are synchronous, `tick()` simulates the asynchronous passage of time.
  553. *
  554. * If there are any pending timers at the end of the function, an exception will be thrown.
  555. *
  556. * Can be used to wrap inject() calls.
  557. *
  558. * ## Example
  559. *
  560. * {@example core/testing/ts/fake_async.ts region='basic'}
  561. *
  562. * @param fn
  563. * @returns The function wrapped to be executed in the fakeAsync zone
  564. *
  565. * @experimental
  566. */
  567. function fakeAsync(fn) {
  568. // Not using an arrow function to preserve context passed from call site
  569. return function () {
  570. var args = [];
  571. for (var _i = 0; _i < arguments.length; _i++) {
  572. args[_i] = arguments[_i];
  573. }
  574. var proxyZoneSpec = ProxyZoneSpec.assertPresent();
  575. if (Zone.current.get('FakeAsyncTestZoneSpec')) {
  576. throw new Error('fakeAsync() calls can not be nested');
  577. }
  578. try {
  579. // in case jasmine.clock init a fakeAsyncTestZoneSpec
  580. if (!_fakeAsyncTestZoneSpec) {
  581. if (proxyZoneSpec.getDelegate() instanceof FakeAsyncTestZoneSpec) {
  582. throw new Error('fakeAsync() calls can not be nested');
  583. }
  584. _fakeAsyncTestZoneSpec = new FakeAsyncTestZoneSpec();
  585. }
  586. var res = void 0;
  587. var lastProxyZoneSpec = proxyZoneSpec.getDelegate();
  588. proxyZoneSpec.setDelegate(_fakeAsyncTestZoneSpec);
  589. _fakeAsyncTestZoneSpec.lockDatePatch();
  590. try {
  591. res = fn.apply(this, args);
  592. flushMicrotasks();
  593. }
  594. finally {
  595. proxyZoneSpec.setDelegate(lastProxyZoneSpec);
  596. }
  597. if (_fakeAsyncTestZoneSpec.pendingPeriodicTimers.length > 0) {
  598. throw new Error(_fakeAsyncTestZoneSpec.pendingPeriodicTimers.length + " " +
  599. "periodic timer(s) still in the queue.");
  600. }
  601. if (_fakeAsyncTestZoneSpec.pendingTimers.length > 0) {
  602. throw new Error(_fakeAsyncTestZoneSpec.pendingTimers.length + " timer(s) still in the queue.");
  603. }
  604. return res;
  605. }
  606. finally {
  607. resetFakeAsyncZone();
  608. }
  609. };
  610. }
  611. function _getFakeAsyncZoneSpec() {
  612. if (_fakeAsyncTestZoneSpec == null) {
  613. _fakeAsyncTestZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
  614. if (_fakeAsyncTestZoneSpec == null) {
  615. throw new Error('The code should be running in the fakeAsync zone to call this function');
  616. }
  617. }
  618. return _fakeAsyncTestZoneSpec;
  619. }
  620. /**
  621. * Simulates the asynchronous passage of time for the timers in the fakeAsync zone.
  622. *
  623. * The microtasks queue is drained at the very start of this function and after any timer callback
  624. * has been executed.
  625. *
  626. * ## Example
  627. *
  628. * {@example core/testing/ts/fake_async.ts region='basic'}
  629. *
  630. * @experimental
  631. */
  632. function tick(millis) {
  633. if (millis === void 0) { millis = 0; }
  634. _getFakeAsyncZoneSpec().tick(millis);
  635. }
  636. /**
  637. * Simulates the asynchronous passage of time for the timers in the fakeAsync zone by
  638. * draining the macrotask queue until it is empty. The returned value is the milliseconds
  639. * of time that would have been elapsed.
  640. *
  641. * @param maxTurns
  642. * @returns The simulated time elapsed, in millis.
  643. *
  644. * @experimental
  645. */
  646. function flush(maxTurns) {
  647. return _getFakeAsyncZoneSpec().flush(maxTurns);
  648. }
  649. /**
  650. * Discard all remaining periodic tasks.
  651. *
  652. * @experimental
  653. */
  654. function discardPeriodicTasks() {
  655. var zoneSpec = _getFakeAsyncZoneSpec();
  656. var pendingTimers = zoneSpec.pendingPeriodicTimers;
  657. zoneSpec.pendingPeriodicTimers.length = 0;
  658. }
  659. /**
  660. * Flush any pending microtasks.
  661. *
  662. * @experimental
  663. */
  664. function flushMicrotasks() {
  665. _getFakeAsyncZoneSpec().flushMicrotasks();
  666. }
  667. Zone[api.symbol('fakeAsyncTest')] =
  668. { resetFakeAsyncZone: resetFakeAsyncZone, flushMicrotasks: flushMicrotasks, discardPeriodicTasks: discardPeriodicTasks, tick: tick, flush: flush, fakeAsync: fakeAsync };
  669. });
  670. })));