import { Result } from '@praha/byethrow'; import { describe, expect, it, vi } from 'vitest'; import { retry } from './retry.js'; type Fn = () => Result.ResultAsync; describe('retry', () => { it('should return success result immediately when function succeeds on first attempt', async () => { const mockFn = vi.fn().mockResolvedValue(Result.succeed('success')); const retryFn = retry(2)(mockFn); const result = await retryFn(); expect(mockFn).toHaveBeenCalledTimes(1); expect(result).toBeSuccess((value) => { expect(value).toBe('success'); }); }); it('should retry when function fails and eventually succeed', async () => { const mockFn = vi.fn() .mockResolvedValueOnce(Result.fail('failure')) .mockResolvedValueOnce(Result.fail('failure')) .mockResolvedValueOnce(Result.succeed('success')); const retryFn = retry(2)(mockFn); const result = await retryFn(); expect(mockFn).toHaveBeenCalledTimes(3); expect(result).toBeSuccess((value) => { expect(value).toBe('success'); }); }); it('should stop retrying after maximum attempts and return last failure', async () => { const mockFn = vi.fn().mockResolvedValue(Result.fail('failure')); const retryFn = retry(2)(mockFn); const result = await Result.unwrapError(retryFn()); expect(result).toBe('failure'); expect(mockFn).toHaveBeenCalledTimes(3); }); });