forked from AubaidFarrukh/smart-retry
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.test.ts
More file actions
122 lines (105 loc) · 4.4 KB
/
Copy pathutils.test.ts
File metadata and controls
122 lines (105 loc) · 4.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import {
generateId,
calculateDelay,
defaultShouldRetry,
sleep,
getErrorMessage,
getStatusCode,
} from '../src/utils';
describe('Utils', () => {
describe('generateId', () => {
it('should generate a valid UUID', () => {
const id = generateId();
expect(id).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/);
});
it('should generate unique IDs', () => {
const id1 = generateId();
const id2 = generateId();
expect(id1).not.toBe(id2);
});
});
describe('calculateDelay', () => {
it('should calculate exponential backoff correctly', () => {
expect(calculateDelay(1000, 1, 'exponential')).toBe(1000);
expect(calculateDelay(1000, 2, 'exponential')).toBe(2000);
expect(calculateDelay(1000, 3, 'exponential')).toBe(4000);
expect(calculateDelay(1000, 4, 'exponential')).toBe(8000);
});
it('should calculate linear backoff correctly', () => {
expect(calculateDelay(1000, 1, 'linear')).toBe(1000);
expect(calculateDelay(1000, 2, 'linear')).toBe(2000);
expect(calculateDelay(1000, 3, 'linear')).toBe(3000);
expect(calculateDelay(1000, 4, 'linear')).toBe(4000);
});
it('should return fixed delay for none backoff', () => {
expect(calculateDelay(1000, 1, 'none')).toBe(1000);
expect(calculateDelay(1000, 2, 'none')).toBe(1000);
expect(calculateDelay(1000, 3, 'none')).toBe(1000);
});
});
describe('defaultShouldRetry', () => {
it('should retry on network errors', () => {
expect(defaultShouldRetry({ code: 'ECONNREFUSED' })).toBe(true);
expect(defaultShouldRetry({ code: 'ETIMEDOUT' })).toBe(true);
expect(defaultShouldRetry({ code: 'ENOTFOUND' })).toBe(true);
expect(defaultShouldRetry({ code: 'ECONNRESET' })).toBe(true);
});
it('should retry on 5xx errors', () => {
expect(defaultShouldRetry({ response: { status: 500 } })).toBe(true);
expect(defaultShouldRetry({ response: { status: 502 } })).toBe(true);
expect(defaultShouldRetry({ response: { status: 503 } })).toBe(true);
expect(defaultShouldRetry({ response: { status: 504 } })).toBe(true);
});
it('should retry on 408 and 429', () => {
expect(defaultShouldRetry({ response: { status: 408 } })).toBe(true);
expect(defaultShouldRetry({ response: { status: 429 } })).toBe(true);
});
it('should not retry on 4xx errors (except 408, 429)', () => {
expect(defaultShouldRetry({ response: { status: 400 } })).toBe(false);
expect(defaultShouldRetry({ response: { status: 401 } })).toBe(false);
expect(defaultShouldRetry({ response: { status: 403 } })).toBe(false);
expect(defaultShouldRetry({ response: { status: 404 } })).toBe(false);
});
it('should not retry on null/undefined', () => {
expect(defaultShouldRetry(null)).toBe(false);
expect(defaultShouldRetry(undefined)).toBe(false);
});
it('should not retry on errors without a status or known network code', () => {
expect(defaultShouldRetry(new TypeError('Cannot read properties of undefined'))).toBe(false);
expect(defaultShouldRetry({ message: 'boom' })).toBe(false);
});
});
describe('sleep', () => {
it('should delay for specified milliseconds', async () => {
const start = Date.now();
await sleep(100);
const duration = Date.now() - start;
expect(duration).toBeGreaterThanOrEqual(95);
expect(duration).toBeLessThan(150);
});
});
describe('getErrorMessage', () => {
it('should extract message from response statusText', () => {
const error = { response: { statusText: 'Not Found' } };
expect(getErrorMessage(error)).toBe('Not Found');
});
it('should extract message from error.message', () => {
const error = new Error('Connection timeout');
expect(getErrorMessage(error)).toBe('Connection timeout');
});
it('should convert to string for unknown errors', () => {
expect(getErrorMessage('string error')).toBe('string error');
expect(getErrorMessage(123)).toBe('123');
});
});
describe('getStatusCode', () => {
it('should extract status code from error', () => {
const error = { response: { status: 404 } };
expect(getStatusCode(error)).toBe(404);
});
it('should return undefined for non-HTTP errors', () => {
const error = new Error('Network error');
expect(getStatusCode(error)).toBeUndefined();
});
});
});