Skip to content

Commit 12eb8a7

Browse files
committed
fix(tests): reduce flakiness
1 parent ed49645 commit 12eb8a7

23 files changed

Lines changed: 1614 additions & 1404 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ test.js
55
dist/
66
.env
77
.env.*
8+
.context/

.oxfmtrc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@
1616
"sortPackageJson": {
1717
"sortScripts": true
1818
},
19-
"ignorePatterns": ["dist/**"]
19+
"ignorePatterns": ["dist/**", ".context/**"]
2020
}

.oxlintrc.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"options": {
1414
"reportUnusedDisableDirectives": "error"
1515
},
16-
"ignorePatterns": ["**/.gitignore", "**/node_modules", "dist/**", "test.ts"],
16+
"ignorePatterns": ["**/.gitignore", "**/node_modules", "dist/**", ".context/**", "test.ts"],
1717
"rules": {
1818
"no-unused-vars": [
1919
"warn",
@@ -32,6 +32,7 @@
3232
"no-await-in-loop": "off",
3333
"no-underscore-dangle": "off", // Disabled because it's a common pattern in the codebase
3434
"no-array-constructor": "error",
35+
"prefer-arrow-callback": "warn",
3536
"typescript/no-explicit-any": "off", // Disabled because it's a common pattern in the codebase
3637
"typescript/no-require-imports": "off", // Disabled because it's a common pattern in the codebase
3738
"typescript/no-unsafe-function-type": "error",

test/batcher.test.js

Lines changed: 19 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,14 @@
1-
import { describe, it, expect, afterEach } from "vitest";
1+
import { useFakeClock, wait } from "./helpers/clock.js";
2+
import { test, describe, expect } from "./helpers/test-api.js";
23
const Bottleneck = require("./bottleneck");
34

4-
const wait = function (ms) {
5-
return new Promise(function (resolve) {
6-
setTimeout(resolve, ms);
7-
});
8-
};
9-
10-
describe("Batcher", function () {
11-
let limiter;
12-
13-
afterEach(function () {
14-
if (limiter) return limiter.disconnect(false);
15-
});
5+
// Batcher is datastore-independent, so this file only runs in the `local`
6+
// project (excluded from the redis projects in vitest.config.ts) and always
7+
// gets the fake clock — timing assertions below are exact virtual times.
8+
useFakeClock();
169

17-
it("Should batch by time and size", async function () {
18-
limiter = new Bottleneck();
10+
describe("Batcher", () => {
11+
test("Should batch by time and size", async function () {
1912
const batcher = new Bottleneck.Batcher({ maxTime: 100, maxSize: 3 });
2013
const batches = [];
2114
const batchTimes = [];
@@ -32,12 +25,11 @@ describe("Batcher", function () {
3225
[1, 2, 3],
3326
[4, 5],
3427
]);
35-
expect(batchTimes[0] - t0).toBeLessThan(20);
36-
expect(batchTimes[1] - batchTimes[0]).toBeGreaterThanOrEqual(95);
28+
expect(batchTimes[0] - t0).toBe(0);
29+
expect(batchTimes[1] - batchTimes[0]).toBe(100);
3730
});
3831

39-
it("Should batch by time", async function () {
40-
limiter = new Bottleneck();
32+
test("Should batch by time", async function () {
4133
const batcher = new Bottleneck.Batcher({ maxTime: 100 });
4234
const batches = [];
4335
const batchTimes = [];
@@ -51,7 +43,7 @@ describe("Batcher", function () {
5143
await Promise.all([batcher.add(1), batcher.add(2)]);
5244

5345
expect(batches).toStrictEqual([[1, 2]]);
54-
expect(batchTimes[0] - t0).toBeGreaterThanOrEqual(95);
46+
expect(batchTimes[0] - t0).toBe(100);
5547

5648
const t1 = Date.now();
5749
await Promise.all([batcher.add(3), batcher.add(4)]);
@@ -60,11 +52,10 @@ describe("Batcher", function () {
6052
[1, 2],
6153
[3, 4],
6254
]);
63-
expect(batchTimes[1] - t1).toBeGreaterThanOrEqual(95);
55+
expect(batchTimes[1] - t1).toBe(100);
6456
});
6557

66-
it("Should batch by size", async function () {
67-
limiter = new Bottleneck();
58+
test("Should batch by size", async function () {
6859
const batcher = new Bottleneck.Batcher({ maxSize: 2 });
6960
const batches = [];
7061

@@ -82,8 +73,7 @@ describe("Batcher", function () {
8273
]);
8374
});
8475

85-
it("Should stagger flushes", async function () {
86-
limiter = new Bottleneck();
76+
test("Should stagger flushes", async function () {
8777
const batcher = new Bottleneck.Batcher({ maxTime: 100, maxSize: 3 });
8878
const batches = [];
8979
const batchTimes = [];
@@ -100,19 +90,10 @@ describe("Batcher", function () {
10090
await Promise.all([p1, p2]);
10191

10292
expect(batches).toStrictEqual([[1, 2]]);
103-
const elapsed = batchTimes[0] - t0;
104-
// Lower bound is the contract: the flush MUST wait for maxTime=100ms
105-
// since adding p2 mid-window must not reset (or shorten) the flush
106-
// timer. The upper bound is just a sanity check — under sustained
107-
// event-loop pressure (parallel test files, redis containers booting,
108-
// GC) setTimeout can drift well past maxTime+40ms; the original 140ms
109-
// upper bound was flaky for that reason.
110-
expect(elapsed).toBeGreaterThanOrEqual(95);
111-
expect(elapsed).toBeLessThan(1000);
93+
expect(batchTimes[0] - t0).toBe(100);
11294
});
11395

114-
it("Should force then stagger flushes", async function () {
115-
limiter = new Bottleneck();
96+
test("Should force then stagger flushes", async function () {
11697
const batcher = new Bottleneck.Batcher({ maxTime: 100, maxSize: 3 });
11798
const batches = [];
11899
const batchTimes = [];
@@ -125,7 +106,7 @@ describe("Batcher", function () {
125106
const t0 = Date.now();
126107
await Promise.all([batcher.add(1), batcher.add(2), batcher.add(3)]);
127108
expect(batches).toStrictEqual([[1, 2, 3]]);
128-
expect(batchTimes[0] - t0).toBeLessThan(20);
109+
expect(batchTimes[0] - t0).toBe(0);
129110

130111
const t1 = Date.now();
131112
const p4 = batcher.add(4);
@@ -137,8 +118,6 @@ describe("Batcher", function () {
137118
[1, 2, 3],
138119
[4, 5],
139120
]);
140-
const elapsed = batchTimes[1] - t1;
141-
expect(elapsed).toBeGreaterThanOrEqual(95);
142-
expect(elapsed).toBeLessThan(140);
121+
expect(batchTimes[1] - t1).toBe(100);
143122
});
144123
});

0 commit comments

Comments
 (0)