jest-time-helpers 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +10 -3
- package/dist/index.js +72 -69
- package/dist/index.js.map +1 -1
- package/package.json +9 -7
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @param ts - how long to sleep for.
|
|
6
6
|
*/
|
|
7
|
-
export declare const sleep: (ms: number) => Promise<void
|
|
7
|
+
export declare const sleep: (ms: number, unref?: boolean) => Promise<void> & {
|
|
8
|
+
timeout: NodeJS.Timeout;
|
|
9
|
+
};
|
|
8
10
|
/**
|
|
9
11
|
* Polls until the condition passes.
|
|
10
12
|
*
|
|
@@ -17,6 +19,10 @@ export declare const sleep: (ms: number) => Promise<void>;
|
|
|
17
19
|
* @param pollInterval - an optional period of how long we should wait between checks; lower values increase load on the server but may make tests pass faster, larger values are more efficient but increase test latency.
|
|
18
20
|
*/
|
|
19
21
|
export declare function sleepUntil(condition: () => boolean, maxDuration?: number, pollInterval?: number): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Returns the real-world current timestamp (unaffected by fake timers).
|
|
24
|
+
*/
|
|
25
|
+
declare function realNow(): number;
|
|
20
26
|
/**
|
|
21
27
|
* Sets up fake timers and Date implementation within your Jest test file. You
|
|
22
28
|
* should call this at the top of the file (**not** within a test or an
|
|
@@ -32,8 +38,8 @@ export declare function sleepUntil(condition: () => boolean, maxDuration?: numbe
|
|
|
32
38
|
* offset.
|
|
33
39
|
*/
|
|
34
40
|
export declare function setupFakeTimers(): {
|
|
35
|
-
setTime: (
|
|
36
|
-
realNow:
|
|
41
|
+
setTime: (targetTimestamp: number, increment?: number) => Promise<void>;
|
|
42
|
+
realNow: typeof realNow;
|
|
37
43
|
};
|
|
38
44
|
/** One second in milliseconds */
|
|
39
45
|
export declare const SECOND = 1000;
|
|
@@ -45,3 +51,4 @@ export declare const HOUR: number;
|
|
|
45
51
|
export declare const DAY: number;
|
|
46
52
|
/** One week in milliseconds */
|
|
47
53
|
export declare const WEEK: number;
|
|
54
|
+
export {};
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,43 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WEEK = exports.DAY = exports.HOUR = exports.MINUTE = exports.SECOND = exports.
|
|
4
|
-
|
|
5
|
-
|
|
36
|
+
exports.WEEK = exports.DAY = exports.HOUR = exports.MINUTE = exports.SECOND = exports.sleep = void 0;
|
|
37
|
+
exports.sleepUntil = sleepUntil;
|
|
38
|
+
exports.setupFakeTimers = setupFakeTimers;
|
|
39
|
+
const assert = __importStar(require("assert"));
|
|
40
|
+
const util = __importStar(require("util"));
|
|
6
41
|
// Grab the setTimeout from global before jest overwrites it with useFakeTimers
|
|
7
42
|
const setTimeoutBypassingFakes = global.setTimeout;
|
|
8
43
|
/**
|
|
@@ -11,7 +46,16 @@ const setTimeoutBypassingFakes = global.setTimeout;
|
|
|
11
46
|
*
|
|
12
47
|
* @param ts - how long to sleep for.
|
|
13
48
|
*/
|
|
14
|
-
const sleep = (ms
|
|
49
|
+
const sleep = (ms, unref = false) => {
|
|
50
|
+
let timeout;
|
|
51
|
+
const promise = new Promise((resolve) => {
|
|
52
|
+
timeout = setTimeoutBypassingFakes(resolve, ms);
|
|
53
|
+
});
|
|
54
|
+
if (unref) {
|
|
55
|
+
timeout.unref();
|
|
56
|
+
}
|
|
57
|
+
return Object.assign(promise, { timeout });
|
|
58
|
+
};
|
|
15
59
|
exports.sleep = sleep;
|
|
16
60
|
/**
|
|
17
61
|
* Polls until the condition passes.
|
|
@@ -33,7 +77,7 @@ async function sleepUntil(condition, maxDuration = 2000, pollInterval = 2) {
|
|
|
33
77
|
// Wait for condition to pass
|
|
34
78
|
const start = Date.now();
|
|
35
79
|
while (Date.now() - start < maxDuration) {
|
|
36
|
-
await exports.sleep(pollInterval);
|
|
80
|
+
await (0, exports.sleep)(pollInterval);
|
|
37
81
|
if (condition()) {
|
|
38
82
|
// Success
|
|
39
83
|
return;
|
|
@@ -42,7 +86,6 @@ async function sleepUntil(condition, maxDuration = 2000, pollInterval = 2) {
|
|
|
42
86
|
// maxDuration exceeded
|
|
43
87
|
throw new Error(`Slept for ${Date.now() - start}ms but condition never passed`);
|
|
44
88
|
}
|
|
45
|
-
exports.sleepUntil = sleepUntil;
|
|
46
89
|
/**
|
|
47
90
|
* This is for letting the Node.js event loop advance, e.g. when `setTimeout`
|
|
48
91
|
* has `await` in the chain.
|
|
@@ -51,9 +94,16 @@ exports.sleepUntil = sleepUntil;
|
|
|
51
94
|
*/
|
|
52
95
|
async function aFewRunLoops(count = 5) {
|
|
53
96
|
for (let i = 0; i < count; i++) {
|
|
54
|
-
await exports.sleep(0);
|
|
97
|
+
await (0, exports.sleep)(0);
|
|
55
98
|
}
|
|
56
99
|
}
|
|
100
|
+
const OriginalDate = global.Date;
|
|
101
|
+
/**
|
|
102
|
+
* Returns the real-world current timestamp (unaffected by fake timers).
|
|
103
|
+
*/
|
|
104
|
+
function realNow() {
|
|
105
|
+
return OriginalDate.now();
|
|
106
|
+
}
|
|
57
107
|
/**
|
|
58
108
|
* Sets up fake timers and Date implementation within your Jest test file. You
|
|
59
109
|
* should call this at the top of the file (**not** within a test or an
|
|
@@ -69,91 +119,44 @@ async function aFewRunLoops(count = 5) {
|
|
|
69
119
|
* offset.
|
|
70
120
|
*/
|
|
71
121
|
function setupFakeTimers() {
|
|
72
|
-
jest.useFakeTimers();
|
|
73
|
-
|
|
74
|
-
/** The offset, in milliseconds, to apply to results from `Date.now()` */
|
|
75
|
-
let offset = 0;
|
|
76
|
-
function fakeNow() {
|
|
77
|
-
return OriginalDate.now() + offset;
|
|
78
|
-
}
|
|
122
|
+
beforeEach(() => void jest.useFakeTimers());
|
|
123
|
+
afterEach(() => void jest.useRealTimers());
|
|
79
124
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*/
|
|
83
|
-
const FakeDate = function (...args) {
|
|
84
|
-
if (args.length === 0) {
|
|
85
|
-
// `new Date()` becomes `new Date(fakeNow())`
|
|
86
|
-
return new OriginalDate(fakeNow());
|
|
87
|
-
}
|
|
88
|
-
else if (args.length === 1) {
|
|
89
|
-
// As before
|
|
90
|
-
return new OriginalDate(args[0]);
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
// As before
|
|
94
|
-
return new OriginalDate(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
// Copy static methods of Date, overriding Date.now()
|
|
98
|
-
FakeDate.now = () => fakeNow();
|
|
99
|
-
FakeDate.parse = Date.parse;
|
|
100
|
-
FakeDate.UTC = Date.UTC;
|
|
101
|
-
/**
|
|
102
|
-
* Sets the `offset` such that a call to `Date.now()` (or `new Date()`) would
|
|
103
|
-
* return this timestamp if called immediately (but time continues to
|
|
125
|
+
* Sets the fake time such that a call to `Date.now()` (or `new Date()`)
|
|
126
|
+
* would return this timestamp if called immediately (but time continues to
|
|
104
127
|
* progress as expected after this). Also advances the timers by the
|
|
105
|
-
* difference from the previous
|
|
106
|
-
*
|
|
107
|
-
*
|
|
128
|
+
* difference from the previous time, if positive. Setting time backwards is
|
|
129
|
+
* allowed (like setting back the system clock on a computer), but will not
|
|
130
|
+
* advance (or undo the advancement of) any timers.
|
|
108
131
|
*
|
|
109
132
|
* Since advancing the time a few hours might not run all the intermediary
|
|
110
133
|
* code quite right, we actually step it up by a configurable increment
|
|
111
134
|
* (defaults to one minute) at a time. Setting time backwards (no matter how
|
|
112
135
|
* far back) is done all at once.
|
|
113
136
|
*
|
|
114
|
-
* @param
|
|
137
|
+
* @param targetTimestamp - the target timestamp
|
|
115
138
|
* @param increment - the maximum we should advance time by at once in order to step towards `timestamp`
|
|
116
139
|
*/
|
|
117
|
-
async function setTime(
|
|
118
|
-
assert.strictEqual(typeof
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (advancement < 0) {
|
|
122
|
-
offset = finalOffset;
|
|
140
|
+
async function setTime(targetTimestamp, increment = exports.MINUTE) {
|
|
141
|
+
assert.strictEqual(typeof targetTimestamp, "number", `Expected \`setTime\` to be passed a number of milliseconds, instead received '${util.inspect(targetTimestamp)}'`);
|
|
142
|
+
if (targetTimestamp < Date.now()) {
|
|
143
|
+
jest.setSystemTime(targetTimestamp);
|
|
123
144
|
}
|
|
124
145
|
else {
|
|
125
|
-
|
|
126
|
-
while (previousOffset + increment < finalOffset) {
|
|
127
|
-
offset = previousOffset + increment;
|
|
128
|
-
previousOffset = offset;
|
|
146
|
+
while (Date.now() + increment < targetTimestamp) {
|
|
129
147
|
jest.advanceTimersByTime(increment);
|
|
130
148
|
await aFewRunLoops();
|
|
131
149
|
}
|
|
132
|
-
if (
|
|
133
|
-
|
|
134
|
-
jest.advanceTimersByTime(finalOffset - previousOffset);
|
|
150
|
+
if (Date.now() < targetTimestamp) {
|
|
151
|
+
jest.advanceTimersByTime(targetTimestamp - Date.now());
|
|
135
152
|
await aFewRunLoops();
|
|
136
153
|
}
|
|
137
154
|
}
|
|
138
155
|
}
|
|
139
|
-
beforeEach(() => {
|
|
140
|
-
offset = 0;
|
|
141
|
-
global.Date = FakeDate;
|
|
142
|
-
});
|
|
143
|
-
afterEach(() => {
|
|
144
|
-
global.Date = OriginalDate;
|
|
145
|
-
});
|
|
146
|
-
/**
|
|
147
|
-
* Returns the real-world current timestamp (unaffected by fake timers).
|
|
148
|
-
*/
|
|
149
|
-
function realNow() {
|
|
150
|
-
return OriginalDate.now();
|
|
151
|
-
}
|
|
152
156
|
// In future we may add other methods such as `setTimeWithoutAdvancingTimers`
|
|
153
157
|
// to emulate the system clock changing without real time elapsing.
|
|
154
158
|
return { setTime, realNow };
|
|
155
159
|
}
|
|
156
|
-
exports.setupFakeTimers = setupFakeTimers;
|
|
157
160
|
/** One second in milliseconds */
|
|
158
161
|
exports.SECOND = 1000;
|
|
159
162
|
/** One minute in milliseconds */
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jest-time-helpers",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Helpers you can use in tests that relate to the passage of time (i.e. code that involves setTimeout, setInterval, new Date(), Date.now(), etc)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"lint": "yarn prettier:check && eslint --ext .js,.jsx,.ts,.tsx,.graphql .",
|
|
11
11
|
"lint:fix": "eslint --ext .js,.jsx,.ts,.tsx,.graphql . --fix; prettier --ignore-path .eslintignore --write '**/*.{js,jsx,ts,tsx,graphql,md,json}'",
|
|
12
12
|
"prettier:check": "prettier --ignore-path .eslintignore --check '**/*.{js,jsx,ts,tsx,graphql,md,json}'",
|
|
13
|
-
"test": "jest && depcheck",
|
|
13
|
+
"test": "yarn prepack && jest && depcheck --ignores @types/*,@tsconfig/*",
|
|
14
14
|
"preversion": "grep '^### Pending' RELEASE_NOTES.md && echo \"⚠️ Cannot publish with 'Pending' in RELEASE_NOTES ⚠️\" && exit 1 || true"
|
|
15
15
|
},
|
|
16
16
|
"repository": {
|
|
@@ -39,10 +39,12 @@
|
|
|
39
39
|
},
|
|
40
40
|
"homepage": "https://github.com/graphile/jest-time-helpers#readme",
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"jest": ">=22 <
|
|
42
|
+
"jest": ">=22 <31"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@
|
|
45
|
+
"@tsconfig/node20": "^20.1.9",
|
|
46
|
+
"@types/jest": "^30.0.0",
|
|
47
|
+
"@types/node": "^20.0.0",
|
|
46
48
|
"@typescript-eslint/eslint-plugin": "^4.13.0",
|
|
47
49
|
"@typescript-eslint/parser": "^4.13.0",
|
|
48
50
|
"depcheck": "^1.3.1",
|
|
@@ -51,11 +53,11 @@
|
|
|
51
53
|
"eslint-plugin-import": "^2.22.1",
|
|
52
54
|
"eslint-plugin-jest": "^24.1.3",
|
|
53
55
|
"eslint-plugin-simple-import-sort": "^7.0.0",
|
|
54
|
-
"jest": "^
|
|
56
|
+
"jest": "^30.2.0",
|
|
55
57
|
"prettier": "^2.2.1",
|
|
56
|
-
"ts-jest": "^
|
|
58
|
+
"ts-jest": "^29.4.6",
|
|
57
59
|
"typedoc": "^0.20.14",
|
|
58
|
-
"typescript": "^
|
|
60
|
+
"typescript": "^5.9.3"
|
|
59
61
|
},
|
|
60
62
|
"files": [
|
|
61
63
|
"dist"
|