summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle June <kylejune1415@gmail.com>2020-07-04 15:16:27 -0400
committerGitHub <noreply@github.com>2020-07-04 15:16:27 -0400
commitd52e4007c887caaa073e43088fd92c3589a41dd5 (patch)
treebc8696eaff52eaddb84b5f2b7f3cc285c8b4a888
parent5f9e600c5bb78ae35a9a12d250f1d7cad79cf7a4 (diff)
Update timers to ignore Date Override (#6552)
-rw-r--r--cli/js/web/timers.ts12
-rw-r--r--cli/tests/unit/timers_test.ts34
2 files changed, 42 insertions, 4 deletions
diff --git a/cli/js/web/timers.ts b/cli/js/web/timers.ts
index 245d6a8c7..74347ee7c 100644
--- a/cli/js/web/timers.ts
+++ b/cli/js/web/timers.ts
@@ -4,6 +4,7 @@ import { startGlobalTimer, stopGlobalTimer } from "../ops/timers.ts";
import { RBTree } from "../rbtree.ts";
const { console } = globalThis;
+const OriginalDate = Date;
interface Timer {
id: number;
@@ -71,7 +72,7 @@ async function setGlobalTimeout(due: number, now: number): Promise<void> {
}
function prepareReadyTimers(): void {
- const now = Date.now();
+ const now = OriginalDate.now();
// Bail out if we're not expecting the global timer to fire.
if (globalTimeoutDue === null || pendingEvents > 0) {
return;
@@ -145,7 +146,10 @@ function unschedule(timer: Timer): void {
// still exists is due, and update the global alarm accordingly.
if (timer.due === globalTimeoutDue) {
const nextDueNode: DueNode | null = dueTree.min();
- setOrClearGlobalTimeout(nextDueNode && nextDueNode.due, Date.now());
+ setOrClearGlobalTimeout(
+ nextDueNode && nextDueNode.due,
+ OriginalDate.now()
+ );
}
} else {
// Multiple timers that are due at the same point in time.
@@ -169,7 +173,7 @@ function fire(timer: Timer): void {
} else {
// Interval timer: compute when timer was supposed to fire next.
// However make sure to never schedule the next interval in the past.
- const now = Date.now();
+ const now = OriginalDate.now();
timer.due = Math.max(now, timer.due + timer.delay);
schedule(timer, now);
}
@@ -205,7 +209,7 @@ function setTimer(
// In the browser, the delay value must be coercible to an integer between 0
// and INT32_MAX. Any other value will cause the timer to fire immediately.
// We emulate this behavior.
- const now = Date.now();
+ const now = OriginalDate.now();
if (delay > TIMEOUT_MAX) {
console.warn(
`${delay} does not fit into` +
diff --git a/cli/tests/unit/timers_test.ts b/cli/tests/unit/timers_test.ts
index 7adff0095..8a22173de 100644
--- a/cli/tests/unit/timers_test.ts
+++ b/cli/tests/unit/timers_test.ts
@@ -366,3 +366,37 @@ unitTest(async function timerNestedMicrotaskOrdering(): Promise<void> {
unitTest(function testQueueMicrotask() {
assertEquals(typeof queueMicrotask, "function");
});
+
+unitTest(async function timerIgnoresDateOverride(): Promise<void> {
+ const OriginalDate = Date;
+ const { promise, resolve, reject } = deferred();
+ let hasThrown = 0;
+ try {
+ const overrideCalled: () => number = () => {
+ reject("global Date override used over original Date object");
+ return 0;
+ };
+ function DateOverride(): void {
+ overrideCalled();
+ }
+ globalThis.Date = DateOverride as DateConstructor;
+ globalThis.Date.now = overrideCalled;
+ globalThis.Date.UTC = overrideCalled;
+ globalThis.Date.parse = overrideCalled;
+ queueMicrotask(resolve);
+ await promise;
+ hasThrown = 1;
+ } catch (err) {
+ if (typeof err === "string") {
+ assertEquals(err, "global Date override used over original Date object");
+ hasThrown = 2;
+ } else if (err instanceof TypeError) {
+ hasThrown = 3;
+ } else {
+ hasThrown = 4;
+ }
+ } finally {
+ globalThis.Date = OriginalDate;
+ }
+ assertEquals(hasThrown, 1);
+});