import { Either } from '../lib/index'; describe('Either.basic', () => { test('mapRight/mapLeft/swap', () => { const r = Either.right(2) .mapRight((n) => n + 1) .mapLeft((e) => e.toUpperCase()); expect(r.right().get()).toBe(3); expect(r.swap().left().get()).toBe(3); const l = Either.left('nope').mapRight((n) => n + 1); expect(l.left().get()).toBe('nope'); expect(l.swap().right().get()).toBe('nope'); }); test('joinRight combines rights', () => { const a = Either.right(2); const b = Either.right(3); const res = a.joinRight(b, (x, y) => x + y); expect(res.right().get()).toBe(5); }); }); describe('Either.retrying', () => { beforeEach(() => { jest.clearAllMocks(); }); test('succeeds on first attempt', async () => { const supplier = jest.fn().mockResolvedValue(Either.right('success')); const interval = jest.fn().mockResolvedValue(undefined); const result = await Either.retrying(supplier, 3, interval); expect(result.right().get()).toBe('success'); expect(supplier).toHaveBeenCalledTimes(1); }); test('never succeeds after all attempts', async () => { const supplier = jest.fn().mockResolvedValue(Either.left('failed')); const interval = jest.fn().mockResolvedValue(undefined); const result = await Either.retrying(supplier, 3, interval); expect(result.left().get()).toBe('failed'); expect(supplier).toHaveBeenCalledTimes(3); }); test('attempts correct number of times and calls interval with backoff', async () => { const supplier = jest .fn() .mockResolvedValueOnce(Either.left('attempt 1 failed')) .mockResolvedValueOnce(Either.left('attempt 2 failed')) .mockResolvedValueOnce(Either.right('attempt 3 success')); const interval = jest.fn().mockResolvedValue(undefined); const result = await Either.retrying(supplier, 3, interval); expect(result.right().get()).toBe('attempt 3 success'); expect(supplier).toHaveBeenCalledTimes(3); expect(interval).toHaveBeenCalledTimes(3); expect(interval).toHaveBeenNthCalledWith(1, 0); expect(interval).toHaveBeenNthCalledWith(2, 1); expect(interval).toHaveBeenNthCalledWith(3, 2); }); });