import { mapWithLimit } from './parallel'; describe('mapWithLimit', () => { it('возвращает результаты в порядке входного массива, а не в порядке завершения', async () => { // Первый элемент заведомо медленнее второго — если бы порядок задавало // завершение, они бы поменялись местами. const settled = await mapWithLimit( [30, 0, 10], delay => new Promise(resolve => setTimeout(() => resolve(delay), delay)), { limit: 3 } ); expect(settled.map(s => (s.ok ? s.value : 'err'))).toEqual([30, 0, 10]); }); it('отказ одного элемента не прерывает остальные', async () => { const settled = await mapWithLimit([1, 2, 3], n => n === 2 ? Promise.reject(new Error('bang')) : Promise.resolve(n) ); expect(settled[0]).toEqual({ ok: true, value: 1 }); expect(settled[1].ok).toBe(false); expect(settled[2]).toEqual({ ok: true, value: 3 }); }); it('не превышает предел одновременных запросов', async () => { let running = 0; let peak = 0; await mapWithLimit( [1, 2, 3, 4, 5, 6, 7], () => { running += 1; peak = Math.max(peak, running); return new Promise(resolve => setTimeout(() => { running -= 1; resolve(); }, 5) ); }, { limit: 2 } ); expect(peak).toBe(2); }); it('onSettled вызывается по разу на каждый элемент, включая упавшие', async () => { let done = 0; await mapWithLimit([1, 2, 3], n => (n === 2 ? Promise.reject(new Error('bang')) : Promise.resolve(n)), { onSettled: () => { done += 1; } }); expect(done).toBe(3); }); it('пустой список — пустой результат, fn не вызывается', async () => { const fn = jest.fn(); const settled = await mapWithLimit([], fn); expect(settled).toEqual([]); expect(fn).not.toHaveBeenCalled(); }); });