source: trip-planner-front/node_modules/rxjs/_esm2015/internal/testing/TestScheduler.js@ 8d391a1

Last change on this file since 8d391a1 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 13.6 KB
Line 
1import { Observable } from '../Observable';
2import { Notification } from '../Notification';
3import { ColdObservable } from './ColdObservable';
4import { HotObservable } from './HotObservable';
5import { SubscriptionLog } from './SubscriptionLog';
6import { VirtualTimeScheduler, VirtualAction } from '../scheduler/VirtualTimeScheduler';
7import { AsyncScheduler } from '../scheduler/AsyncScheduler';
8const defaultMaxFrame = 750;
9export 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
Note: See TracBrowser for help on using the repository browser.