maestro/src/engine/async-mutex.test.ts
2026-06-04 00:34:55 +00:00

33 lines
1.1 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { AsyncMutex } from './async-mutex.js';
const tick = () => new Promise((r) => setTimeout(r, 5));
describe('AsyncMutex', () => {
it('runs exclusive sections serially, never overlapping', async () => {
const m = new AsyncMutex();
const log: string[] = [];
const section = (name: string) => m.runExclusive(async () => {
log.push(`${name}:enter`);
await tick();
log.push(`${name}:exit`);
});
await Promise.all([section('A'), section('B'), section('C')]);
// every enter is immediately followed by its own exit (no interleave)
expect(log).toEqual(['A:enter', 'A:exit', 'B:enter', 'B:exit', 'C:enter', 'C:exit']);
});
it('continues the chain after a rejection', async () => {
const m = new AsyncMutex();
const a = m.runExclusive(async () => { throw new Error('boom'); });
await expect(a).rejects.toThrow('boom');
const b = await m.runExclusive(async () => 42);
expect(b).toBe(42);
});
it('returns the section result', async () => {
const m = new AsyncMutex();
expect(await m.runExclusive(async () => 'ok')).toBe('ok');
});
});