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" ;
23const 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