| 290 | * ``` |
| 291 | */ |
| 292 | export class FakeTime { |
| 293 | /** |
| 294 | * Construct a FakeTime object. This overrides the real Date object and timer functions with fake ones that can be |
| 295 | * controlled through the fake time instance. |
| 296 | * |
| 297 | * @param start The time to simulate. The default is the current time. |
| 298 | * @param options The options |
| 299 | * |
| 300 | * @throws {TimeError} If time is already faked |
| 301 | * @throws {TypeError} If the start is invalid |
| 302 | */ |
| 303 | constructor( |
| 304 | start?: number | string | Date | null, |
| 305 | options?: FakeTimeOptions, |
| 306 | ) { |
| 307 | if (time) { |
| 308 | throw new TimeError("Cannot construct FakeTime: time is already faked"); |
| 309 | } |
| 310 | initializedAt = _internals.Date.now(); |
| 311 | startedAt = start instanceof Date |
| 312 | ? start.valueOf() |
| 313 | : typeof start === "number" |
| 314 | ? Math.floor(start) |
| 315 | : typeof start === "string" |
| 316 | ? (new Date(start)).valueOf() |
| 317 | : initializedAt; |
| 318 | if (Number.isNaN(startedAt)) { |
| 319 | throw new TypeError( |
| 320 | `Cannot construct FakeTime: invalid start time ${startedAt}`, |
| 321 | ); |
| 322 | } |
| 323 | now = startedAt; |
| 324 | |
| 325 | timerId = timerIdGen(); |
| 326 | dueNodes = new Map(); |
| 327 | dueTree = new RedBlackTree( |
| 328 | (a: DueNode, b: DueNode) => ascend(a.due, b.due), |
| 329 | ); |
| 330 | |
| 331 | overrideGlobals(); |
| 332 | time = this; |
| 333 | |
| 334 | advanceRate = Math.max( |
| 335 | 0, |
| 336 | options?.advanceRate ?? 0, |
| 337 | ); |
| 338 | advanceFrequency = Math.max( |
| 339 | 0, |
| 340 | options?.advanceFrequency ?? 10, |
| 341 | ); |
| 342 | advanceIntervalId = advanceRate > 0 |
| 343 | ? _internals.setInterval.call(null, () => { |
| 344 | this.tick(advanceRate * advanceFrequency); |
| 345 | }, advanceFrequency) |
| 346 | : undefined; |
| 347 | } |
| 348 | |
| 349 | /** |
nothing calls this directly
no outgoing calls
no test coverage detected