Skip to content

Commit 6971a29

Browse files
committed
Test stability
1 parent 8e9ae4f commit 6971a29

File tree

1 file changed

+28
-32
lines changed

1 file changed

+28
-32
lines changed

src/Bash.exec-options.test.ts

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,18 @@ function createMockClock() {
3434
};
3535
}
3636

37-
// Helper to wait for async operations (command lazy loading, etc.) to complete
38-
// Uses multiple iterations to ensure all microtasks and macrotasks complete
39-
async function tick(times = 50): Promise<void> {
40-
for (let i = 0; i < times; i++) {
41-
await new Promise((r) => setTimeout(r, 0));
37+
// Helper to wait for a condition to be true, with polling
38+
// More reliable than a fixed number of ticks
39+
async function waitFor(
40+
condition: () => boolean,
41+
timeoutMs = 1000,
42+
): Promise<void> {
43+
const start = Date.now();
44+
while (!condition()) {
45+
if (Date.now() - start > timeoutMs) {
46+
throw new Error(`waitFor timed out after ${timeoutMs}ms`);
47+
}
48+
await new Promise((r) => setTimeout(r, 1));
4249
}
4350
}
4451

@@ -293,11 +300,8 @@ describe("exec options", () => {
293300

294301
const promise = env.exec("sleep 1");
295302

296-
// Wait for async command loading
297-
await tick();
298-
299-
// Should be pending
300-
expect(clock.pendingCount).toBe(1);
303+
// Wait for sleep to be registered
304+
await waitFor(() => clock.pendingCount === 1);
301305

302306
// Advance clock
303307
clock.advance(1000);
@@ -314,8 +318,7 @@ describe("exec options", () => {
314318
// Start sleep with minute suffix
315319
const promise = env.exec("sleep 0.5m");
316320

317-
await tick();
318-
expect(clock.pendingCount).toBe(1);
321+
await waitFor(() => clock.pendingCount === 1);
319322

320323
// 30 seconds = 0.5 minutes
321324
clock.advance(30000);
@@ -331,12 +334,11 @@ describe("exec options", () => {
331334
// GNU sleep sums multiple arguments
332335
const promise = env.exec("sleep 1 2");
333336

334-
await tick();
335-
expect(clock.pendingCount).toBe(1);
337+
await waitFor(() => clock.pendingCount === 1);
336338

337-
// First advance - not enough
339+
// First advance - not enough (sleep 1 2 = 3 seconds total)
338340
clock.advance(2000);
339-
await tick();
341+
// pendingCount should still be 1
340342
expect(clock.pendingCount).toBe(1);
341343

342344
// Second advance completes
@@ -357,8 +359,7 @@ describe("exec options", () => {
357359
const p2 = env.exec("sleep 2; echo done2");
358360
const p3 = env.exec("sleep 3; echo done3");
359361

360-
await tick();
361-
expect(clock.pendingCount).toBe(3);
362+
await waitFor(() => clock.pendingCount === 3);
362363

363364
// Advance 1 second - first should complete
364365
clock.advance(1000);
@@ -394,8 +395,7 @@ describe("exec options", () => {
394395
env: { B: "value_B" },
395396
});
396397

397-
await tick();
398-
expect(clock.pendingCount).toBe(2);
398+
await waitFor(() => clock.pendingCount === 2);
399399

400400
// Advance clock to complete both
401401
clock.advance(1000);
@@ -422,8 +422,7 @@ describe("exec options", () => {
422422
// Command 2: read VAR immediately (before p1's sleep completes)
423423
const p2 = env.exec("sleep 1; echo $VAR", { env: { MARKER: "2" } });
424424

425-
await tick();
426-
expect(clock.pendingCount).toBe(2);
425+
await waitFor(() => clock.pendingCount === 2);
427426

428427
// Advance 1 second - p2 completes first
429428
clock.advance(1000);
@@ -458,8 +457,7 @@ describe("exec options", () => {
458457
);
459458
}
460459

461-
await tick();
462-
expect(clock.pendingCount).toBe(10);
460+
await waitFor(() => clock.pendingCount === 10);
463461

464462
// Advance clock to complete all
465463
clock.advance(2000);
@@ -496,8 +494,7 @@ describe("exec options", () => {
496494
{ env: { CMD: "2" } },
497495
);
498496

499-
await tick();
500-
expect(clock.pendingCount).toBe(2);
497+
await waitFor(() => clock.pendingCount === 2);
501498

502499
// Advance 1 second
503500
clock.advance(1000);
@@ -533,8 +530,7 @@ describe("exec options", () => {
533530
const p2 = env.exec("sleep 1; pwd; cat file.txt", { cwd: "/tmp" });
534531
const p3 = env.exec("sleep 1; pwd; cat file.txt", { cwd: "/var" });
535532

536-
await tick();
537-
expect(clock.pendingCount).toBe(3);
533+
await waitFor(() => clock.pendingCount === 3);
538534
clock.advance(1000);
539535

540536
const [r1, r2, r3] = await Promise.all([p1, p2, p3]);
@@ -563,7 +559,7 @@ describe("exec options", () => {
563559
env: { MARKER: "2" },
564560
});
565561

566-
await tick();
562+
await waitFor(() => clock.pendingCount === 2);
567563
clock.advance(1000);
568564
const r1 = await p1;
569565
expect(r1.stdout).toBe("from_p1\n");
@@ -590,7 +586,7 @@ describe("exec options", () => {
590586
env: { MARKER: "2" },
591587
});
592588

593-
await tick();
589+
await waitFor(() => clock.pendingCount === 2);
594590
clock.advance(1000);
595591
const r1 = await p1;
596592
expect(r1.stdout).toBe(""); // errexit stopped execution
@@ -613,7 +609,7 @@ describe("exec options", () => {
613609
const p1 = env.exec("export COUNTER=from_p1; sleep 1; echo done1");
614610
const p2 = env.exec("sleep 2; echo $COUNTER");
615611

616-
await tick();
612+
await waitFor(() => clock.pendingCount === 2);
617613
clock.advance(1000);
618614
await p1;
619615

@@ -641,7 +637,7 @@ describe("exec options", () => {
641637
);
642638
}
643639

644-
await tick();
640+
await waitFor(() => clock.pendingCount === 20);
645641
// Advance clock
646642
clock.advance(100);
647643
const results = await Promise.all(promises);

0 commit comments

Comments
 (0)