1 | ;
|
2 | /**
|
3 | * @module Core
|
4 | */
|
5 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
6 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
7 | };
|
8 | Object.defineProperty(exports, "__esModule", { value: true });
|
9 | exports.Callable = void 0;
|
10 | /*
|
11 | * japa
|
12 | *
|
13 | * (c) Harminder Virk <virk@adonisjs.com>
|
14 | *
|
15 | * For the full copyright and license information, please view the LICENSE
|
16 | * file that was distributed with this source code.
|
17 | */
|
18 | const Exceptions_1 = require("../Exceptions");
|
19 | const debug_1 = __importDefault(require("debug"));
|
20 | /**
|
21 | * @ignore
|
22 | */
|
23 | const debug = (0, debug_1.default)('japa');
|
24 | /**
|
25 | * Executes the function as promise
|
26 | * @ignore
|
27 | */
|
28 | async function asPromise(fn, args) {
|
29 | return fn(...args);
|
30 | }
|
31 | /**
|
32 | * Calls a function and tracks it's completion in multiple ways. If original function
|
33 | * relies on `done`, then it will wait for `done` to be called. Also if timeout is
|
34 | * defined, the function will fail if doesn't return before the timeout.
|
35 | */
|
36 | function Callable(resolveFn, callback, timeout) {
|
37 | return new Promise((resolve, reject) => {
|
38 | let postCallable = null;
|
39 | const args = resolveFn(done, function postRun(fn) {
|
40 | postCallable = fn;
|
41 | });
|
42 | /**
|
43 | * Finding if we need to wait for done to be called
|
44 | */
|
45 | const needsDone = args.length === callback.length;
|
46 | debug('needsDone %s', needsDone);
|
47 | /**
|
48 | * Is callable completed?
|
49 | */
|
50 | let completed = false;
|
51 | /**
|
52 | * Timer to timeout the test, if timeout is defined
|
53 | */
|
54 | let timer = null;
|
55 | /**
|
56 | * Clears the timer if it exists
|
57 | */
|
58 | function clearTimer() {
|
59 | if (timer) {
|
60 | debug('clearing timer');
|
61 | clearTimeout(timer);
|
62 | }
|
63 | }
|
64 | /**
|
65 | * Finish the callable
|
66 | */
|
67 | function finish(error) {
|
68 | if (typeof (postCallable) === 'function' && !error) {
|
69 | try {
|
70 | postCallable(...args);
|
71 | }
|
72 | catch (postCallableError) {
|
73 | error = postCallableError;
|
74 | }
|
75 | }
|
76 | debug(error ? 'finishing callable as error' : 'finishing callable');
|
77 | completed = true;
|
78 | clearTimer();
|
79 | if (error) {
|
80 | reject(error);
|
81 | }
|
82 | else {
|
83 | resolve();
|
84 | }
|
85 | }
|
86 | /**
|
87 | * Done is passed to fn to mark them as completed. When `done`
|
88 | * is used, we need wait for it to be called or timeout.
|
89 | */
|
90 | function done(error) {
|
91 | if (completed) {
|
92 | return;
|
93 | }
|
94 | if (error) {
|
95 | finish(error);
|
96 | return;
|
97 | }
|
98 | finish();
|
99 | }
|
100 | /**
|
101 | * Only set the timer, when timeout is over 0
|
102 | */
|
103 | if (timeout > 0) {
|
104 | debug('creating timer');
|
105 | timer = setTimeout(() => {
|
106 | debug('timeout');
|
107 | /* istanbul ignore else */
|
108 | if (!completed) {
|
109 | finish(new Exceptions_1.TimeoutException(`Test timeout after ${timeout} milliseconds`));
|
110 | }
|
111 | }, timeout);
|
112 | }
|
113 | debug('executing callable');
|
114 | asPromise(callback, args)
|
115 | .then(() => {
|
116 | if (!needsDone) {
|
117 | finish();
|
118 | }
|
119 | })
|
120 | .catch((error) => {
|
121 | finish(error);
|
122 | });
|
123 | });
|
124 | }
|
125 | exports.Callable = Callable;
|