33 lines
1.1 KiB
TypeScript
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');
|
|
});
|
|
});
|