minor adjustment to readme
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / rxjs / _esm2015 / internal / testing / TestScheduler.js
1 import { Observable } from '../Observable';
2 import { Notification } from '../Notification';
3 import { ColdObservable } from './ColdObservable';
4 import { HotObservable } from './HotObservable';
5 import { SubscriptionLog } from './SubscriptionLog';
6 import { VirtualTimeScheduler, VirtualAction } from '../scheduler/VirtualTimeScheduler';
7 import { AsyncScheduler } from '../scheduler/AsyncScheduler';
8 const defaultMaxFrame = 750;
9 export class TestScheduler extends VirtualTimeScheduler {
10     constructor(assertDeepEqual) {
11         super(VirtualAction, defaultMaxFrame);
12         this.assertDeepEqual = assertDeepEqual;
13         this.hotObservables = [];
14         this.coldObservables = [];
15         this.flushTests = [];
16         this.runMode = false;
17     }
18     createTime(marbles) {
19         const indexOf = marbles.indexOf('|');
20         if (indexOf === -1) {
21             throw new Error('marble diagram for time should have a completion marker "|"');
22         }
23         return indexOf * TestScheduler.frameTimeFactor;
24     }
25     createColdObservable(marbles, values, error) {
26         if (marbles.indexOf('^') !== -1) {
27             throw new Error('cold observable cannot have subscription offset "^"');
28         }
29         if (marbles.indexOf('!') !== -1) {
30             throw new Error('cold observable cannot have unsubscription marker "!"');
31         }
32         const messages = TestScheduler.parseMarbles(marbles, values, error, undefined, this.runMode);
33         const cold = new ColdObservable(messages, this);
34         this.coldObservables.push(cold);
35         return cold;
36     }
37     createHotObservable(marbles, values, error) {
38         if (marbles.indexOf('!') !== -1) {
39             throw new Error('hot observable cannot have unsubscription marker "!"');
40         }
41         const messages = TestScheduler.parseMarbles(marbles, values, error, undefined, this.runMode);
42         const subject = new HotObservable(messages, this);
43         this.hotObservables.push(subject);
44         return subject;
45     }
46     materializeInnerObservable(observable, outerFrame) {
47         const messages = [];
48         observable.subscribe((value) => {
49             messages.push({ frame: this.frame - outerFrame, notification: Notification.createNext(value) });
50         }, (err) => {
51             messages.push({ frame: this.frame - outerFrame, notification: Notification.createError(err) });
52         }, () => {
53             messages.push({ frame: this.frame - outerFrame, notification: Notification.createComplete() });
54         });
55         return messages;
56     }
57     expectObservable(observable, subscriptionMarbles = null) {
58         const actual = [];
59         const flushTest = { actual, ready: false };
60         const subscriptionParsed = TestScheduler.parseMarblesAsSubscriptions(subscriptionMarbles, this.runMode);
61         const subscriptionFrame = subscriptionParsed.subscribedFrame === Number.POSITIVE_INFINITY ?
62             0 : subscriptionParsed.subscribedFrame;
63         const unsubscriptionFrame = subscriptionParsed.unsubscribedFrame;
64         let subscription;
65         this.schedule(() => {
66             subscription = observable.subscribe(x => {
67                 let value = x;
68                 if (x instanceof Observable) {
69                     value = this.materializeInnerObservable(value, this.frame);
70                 }
71                 actual.push({ frame: this.frame, notification: Notification.createNext(value) });
72             }, (err) => {
73                 actual.push({ frame: this.frame, notification: Notification.createError(err) });
74             }, () => {
75                 actual.push({ frame: this.frame, notification: Notification.createComplete() });
76             });
77         }, subscriptionFrame);
78         if (unsubscriptionFrame !== Number.POSITIVE_INFINITY) {
79             this.schedule(() => subscription.unsubscribe(), unsubscriptionFrame);
80         }
81         this.flushTests.push(flushTest);
82         const { runMode } = this;
83         return {
84             toBe(marbles, values, errorValue) {
85                 flushTest.ready = true;
86                 flushTest.expected = TestScheduler.parseMarbles(marbles, values, errorValue, true, runMode);
87             }
88         };
89     }
90     expectSubscriptions(actualSubscriptionLogs) {
91         const flushTest = { actual: actualSubscriptionLogs, ready: false };
92         this.flushTests.push(flushTest);
93         const { runMode } = this;
94         return {
95             toBe(marbles) {
96                 const marblesArray = (typeof marbles === 'string') ? [marbles] : marbles;
97                 flushTest.ready = true;
98                 flushTest.expected = marblesArray.map(marbles => TestScheduler.parseMarblesAsSubscriptions(marbles, runMode));
99             }
100         };
101     }
102     flush() {
103         const hotObservables = this.hotObservables;
104         while (hotObservables.length > 0) {
105             hotObservables.shift().setup();
106         }
107         super.flush();
108         this.flushTests = this.flushTests.filter(test => {
109             if (test.ready) {
110                 this.assertDeepEqual(test.actual, test.expected);
111                 return false;
112             }
113             return true;
114         });
115     }
116     static parseMarblesAsSubscriptions(marbles, runMode = false) {
117         if (typeof marbles !== 'string') {
118             return new SubscriptionLog(Number.POSITIVE_INFINITY);
119         }
120         const len = marbles.length;
121         let groupStart = -1;
122         let subscriptionFrame = Number.POSITIVE_INFINITY;
123         let unsubscriptionFrame = Number.POSITIVE_INFINITY;
124         let frame = 0;
125         for (let i = 0; i < len; i++) {
126             let nextFrame = frame;
127             const advanceFrameBy = (count) => {
128                 nextFrame += count * this.frameTimeFactor;
129             };
130             const c = marbles[i];
131             switch (c) {
132                 case ' ':
133                     if (!runMode) {
134                         advanceFrameBy(1);
135                     }
136                     break;
137                 case '-':
138                     advanceFrameBy(1);
139                     break;
140                 case '(':
141                     groupStart = frame;
142                     advanceFrameBy(1);
143                     break;
144                 case ')':
145                     groupStart = -1;
146                     advanceFrameBy(1);
147                     break;
148                 case '^':
149                     if (subscriptionFrame !== Number.POSITIVE_INFINITY) {
150                         throw new Error('found a second subscription point \'^\' in a ' +
151                             'subscription marble diagram. There can only be one.');
152                     }
153                     subscriptionFrame = groupStart > -1 ? groupStart : frame;
154                     advanceFrameBy(1);
155                     break;
156                 case '!':
157                     if (unsubscriptionFrame !== Number.POSITIVE_INFINITY) {
158                         throw new Error('found a second subscription point \'^\' in a ' +
159                             'subscription marble diagram. There can only be one.');
160                     }
161                     unsubscriptionFrame = groupStart > -1 ? groupStart : frame;
162                     break;
163                 default:
164                     if (runMode && c.match(/^[0-9]$/)) {
165                         if (i === 0 || marbles[i - 1] === ' ') {
166                             const buffer = marbles.slice(i);
167                             const match = buffer.match(/^([0-9]+(?:\.[0-9]+)?)(ms|s|m) /);
168                             if (match) {
169                                 i += match[0].length - 1;
170                                 const duration = parseFloat(match[1]);
171                                 const unit = match[2];
172                                 let durationInMs;
173                                 switch (unit) {
174                                     case 'ms':
175                                         durationInMs = duration;
176                                         break;
177                                     case 's':
178                                         durationInMs = duration * 1000;
179                                         break;
180                                     case 'm':
181                                         durationInMs = duration * 1000 * 60;
182                                         break;
183                                     default:
184                                         break;
185                                 }
186                                 advanceFrameBy(durationInMs / this.frameTimeFactor);
187                                 break;
188                             }
189                         }
190                     }
191                     throw new Error('there can only be \'^\' and \'!\' markers in a ' +
192                         'subscription marble diagram. Found instead \'' + c + '\'.');
193             }
194             frame = nextFrame;
195         }
196         if (unsubscriptionFrame < 0) {
197             return new SubscriptionLog(subscriptionFrame);
198         }
199         else {
200             return new SubscriptionLog(subscriptionFrame, unsubscriptionFrame);
201         }
202     }
203     static parseMarbles(marbles, values, errorValue, materializeInnerObservables = false, runMode = false) {
204         if (marbles.indexOf('!') !== -1) {
205             throw new Error('conventional marble diagrams cannot have the ' +
206                 'unsubscription marker "!"');
207         }
208         const len = marbles.length;
209         const testMessages = [];
210         const subIndex = runMode ? marbles.replace(/^[ ]+/, '').indexOf('^') : marbles.indexOf('^');
211         let frame = subIndex === -1 ? 0 : (subIndex * -this.frameTimeFactor);
212         const getValue = typeof values !== 'object' ?
213             (x) => x :
214             (x) => {
215                 if (materializeInnerObservables && values[x] instanceof ColdObservable) {
216                     return values[x].messages;
217                 }
218                 return values[x];
219             };
220         let groupStart = -1;
221         for (let i = 0; i < len; i++) {
222             let nextFrame = frame;
223             const advanceFrameBy = (count) => {
224                 nextFrame += count * this.frameTimeFactor;
225             };
226             let notification;
227             const c = marbles[i];
228             switch (c) {
229                 case ' ':
230                     if (!runMode) {
231                         advanceFrameBy(1);
232                     }
233                     break;
234                 case '-':
235                     advanceFrameBy(1);
236                     break;
237                 case '(':
238                     groupStart = frame;
239                     advanceFrameBy(1);
240                     break;
241                 case ')':
242                     groupStart = -1;
243                     advanceFrameBy(1);
244                     break;
245                 case '|':
246                     notification = Notification.createComplete();
247                     advanceFrameBy(1);
248                     break;
249                 case '^':
250                     advanceFrameBy(1);
251                     break;
252                 case '#':
253                     notification = Notification.createError(errorValue || 'error');
254                     advanceFrameBy(1);
255                     break;
256                 default:
257                     if (runMode && c.match(/^[0-9]$/)) {
258                         if (i === 0 || marbles[i - 1] === ' ') {
259                             const buffer = marbles.slice(i);
260                             const match = buffer.match(/^([0-9]+(?:\.[0-9]+)?)(ms|s|m) /);
261                             if (match) {
262                                 i += match[0].length - 1;
263                                 const duration = parseFloat(match[1]);
264                                 const unit = match[2];
265                                 let durationInMs;
266                                 switch (unit) {
267                                     case 'ms':
268                                         durationInMs = duration;
269                                         break;
270                                     case 's':
271                                         durationInMs = duration * 1000;
272                                         break;
273                                     case 'm':
274                                         durationInMs = duration * 1000 * 60;
275                                         break;
276                                     default:
277                                         break;
278                                 }
279                                 advanceFrameBy(durationInMs / this.frameTimeFactor);
280                                 break;
281                             }
282                         }
283                     }
284                     notification = Notification.createNext(getValue(c));
285                     advanceFrameBy(1);
286                     break;
287             }
288             if (notification) {
289                 testMessages.push({ frame: groupStart > -1 ? groupStart : frame, notification });
290             }
291             frame = nextFrame;
292         }
293         return testMessages;
294     }
295     run(callback) {
296         const prevFrameTimeFactor = TestScheduler.frameTimeFactor;
297         const prevMaxFrames = this.maxFrames;
298         TestScheduler.frameTimeFactor = 1;
299         this.maxFrames = Number.POSITIVE_INFINITY;
300         this.runMode = true;
301         AsyncScheduler.delegate = this;
302         const helpers = {
303             cold: this.createColdObservable.bind(this),
304             hot: this.createHotObservable.bind(this),
305             flush: this.flush.bind(this),
306             expectObservable: this.expectObservable.bind(this),
307             expectSubscriptions: this.expectSubscriptions.bind(this),
308         };
309         try {
310             const ret = callback(helpers);
311             this.flush();
312             return ret;
313         }
314         finally {
315             TestScheduler.frameTimeFactor = prevFrameTimeFactor;
316             this.maxFrames = prevMaxFrames;
317             this.runMode = false;
318             AsyncScheduler.delegate = undefined;
319         }
320     }
321 }
322 //# sourceMappingURL=TestScheduler.js.map