-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest.js
More file actions
203 lines (174 loc) · 7.34 KB
/
test.js
File metadata and controls
203 lines (174 loc) · 7.34 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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
// httpwut — tests. free forever from vøiddo. https://voiddo.com/tools/httpwut/
const requester = require('./src/requester');
let passed = 0;
let failed = 0;
function test(name, fn) {
try {
fn();
console.log('\x1b[32m✓ ' + name + '\x1b[0m');
passed++;
} catch (e) {
console.log('\x1b[31m✗ ' + name + '\x1b[0m');
console.log(' ' + e.message);
failed++;
}
}
async function asyncTest(name, fn) {
try {
await fn();
console.log('\x1b[32m✓ ' + name + '\x1b[0m');
passed++;
} catch (e) {
console.log('\x1b[31m✗ ' + name + '\x1b[0m');
console.log(' ' + e.message);
failed++;
}
}
function assert(condition, message) {
if (!condition) throw new Error(message || 'Assertion failed');
}
// Test parseHeaders
test('parseHeaders handles single header', () => {
const headers = requester.parseHeaders(['Content-Type: application/json']);
assert(headers['Content-Type'] === 'application/json', 'Should parse header correctly');
});
test('parseHeaders handles multiple headers', () => {
const headers = requester.parseHeaders([
'Content-Type: application/json',
'Authorization: Bearer token123',
'X-Custom: value'
]);
assert(Object.keys(headers).length === 3, 'Should have 3 headers');
assert(headers['Authorization'] === 'Bearer token123', 'Should parse auth header');
});
test('parseHeaders handles header with colons in value', () => {
const headers = requester.parseHeaders(['X-Time: 12:30:45']);
assert(headers['X-Time'] === '12:30:45', 'Should preserve colons in value');
});
// Test isSuccess
test('isSuccess returns true for 2xx', () => {
assert(requester.isSuccess(200) === true, '200 should be success');
assert(requester.isSuccess(201) === true, '201 should be success');
assert(requester.isSuccess(204) === true, '204 should be success');
});
test('isSuccess returns false for non-2xx', () => {
assert(requester.isSuccess(400) === false, '400 should not be success');
assert(requester.isSuccess(404) === false, '404 should not be success');
assert(requester.isSuccess(500) === false, '500 should not be success');
});
// Test getStatusHelp
test('getStatusHelp returns message for known codes', () => {
const help = requester.getStatusHelp(404);
assert(help !== null, 'Should have help for 404');
assert(help.includes('not found'), 'Should mention not found');
});
test('getStatusHelp returns null for unknown codes', () => {
const help = requester.getStatusHelp(200);
assert(help === null, 'Should return null for 200');
});
// Test getErrorHelp
test('getErrorHelp returns message for known errors', () => {
const help = requester.getErrorHelp({ code: 'ECONNREFUSED' });
assert(help.includes('nothing is listening'), 'Should have connection refused help');
});
test('getErrorHelp returns generic message for unknown errors', () => {
const help = requester.getErrorHelp({ message: 'Some error' });
assert(help.includes('Some error'), 'Should include error message');
});
// Test formatJson
test('formatJson formats valid JSON', () => {
const result = requester.formatJson('{"name":"test"}');
assert(result.includes('\n'), 'Should have newlines');
assert(result.includes(' '), 'Should have indentation');
});
test('formatJson returns original for invalid JSON', () => {
const result = requester.formatJson('not json');
assert(result === 'not json', 'Should return original');
});
// Test truncate
test('truncate shortens long strings', () => {
const long = 'a'.repeat(5000);
const result = requester.truncate(long, 100);
assert(result.length < 200, 'Should be truncated');
assert(result.includes('truncated'), 'Should indicate truncation');
});
test('truncate leaves short strings alone', () => {
const short = 'hello';
const result = requester.truncate(short, 100);
assert(result === short, 'Should not modify short string');
});
// Test compareResponses
test('compareResponses detects status difference', () => {
const resp1 = { status: 200, headers: {}, body: 'test', timing: { total: 100 } };
const resp2 = { status: 404, headers: {}, body: 'test', timing: { total: 150 } };
const diff = requester.compareResponses(resp1, resp2);
assert(diff.status === true, 'Should detect status diff');
});
test('compareResponses detects body difference', () => {
const resp1 = { status: 200, headers: {}, body: 'hello', timing: { total: 100 } };
const resp2 = { status: 200, headers: {}, body: 'world', timing: { total: 100 } };
const diff = requester.compareResponses(resp1, resp2);
assert(diff.bodyMatch === false, 'Should detect body diff');
});
test('compareResponses detects header difference', () => {
const resp1 = { status: 200, headers: { 'content-type': 'text/html' }, body: '', timing: { total: 100 } };
const resp2 = { status: 200, headers: { 'content-type': 'application/json' }, body: '', timing: { total: 100 } };
const diff = requester.compareResponses(resp1, resp2);
assert(Object.keys(diff.headers).length > 0, 'Should detect header diff');
});
test('compareResponses calculates timing diff', () => {
const resp1 = { status: 200, headers: {}, body: '', timing: { total: 100 } };
const resp2 = { status: 200, headers: {}, body: '', timing: { total: 150 } };
const diff = requester.compareResponses(resp1, resp2);
assert(diff.timing.diff === 50, 'Should calculate timing diff');
});
// Test ERROR_HELP and STATUS_HELP exist
test('ERROR_HELP has common errors', () => {
assert(requester.ERROR_HELP['ECONNREFUSED'], 'Should have ECONNREFUSED');
assert(requester.ERROR_HELP['ENOTFOUND'], 'Should have ENOTFOUND');
assert(requester.ERROR_HELP['ETIMEDOUT'], 'Should have ETIMEDOUT');
});
test('STATUS_HELP has common status codes', () => {
assert(requester.STATUS_HELP[400], 'Should have 400');
assert(requester.STATUS_HELP[401], 'Should have 401');
assert(requester.STATUS_HELP[404], 'Should have 404');
assert(requester.STATUS_HELP[500], 'Should have 500');
});
async function runAsyncTests() {
// Test makeRequest with real endpoint (skip if network unavailable)
await asyncTest('makeRequest returns response object', async () => {
try {
const resp = await requester.makeRequest('https://example.com');
assert(resp.status !== undefined, 'Should have status');
assert(resp.headers !== undefined, 'Should have headers');
assert(resp.body !== undefined, 'Should have body');
assert(resp.timing !== undefined, 'Should have timing');
} catch (e) {
// Network may be unavailable, skip
if (e.code === 'ENOTFOUND' || e.code === 'ECONNREFUSED' || e.message.includes('socket')) {
console.log(' (skipped - network unavailable)');
return;
}
throw e;
}
});
await asyncTest('makeRequest handles connection error gracefully', async () => {
try {
await requester.makeRequest('https://localhost:59999');
assert(false, 'Should have thrown');
} catch (e) {
assert(e.code === 'ECONNREFUSED' || e.message.includes('ECONNREFUSED'), 'Should get connection refused');
}
});
await asyncTest('makeRequest handles invalid URL', async () => {
try {
await requester.makeRequest('not-a-url');
assert(false, 'Should have thrown');
} catch (e) {
assert(e.message.includes('Invalid URL'), 'Should throw invalid URL error');
}
});
console.log('\n' + passed + '/' + (passed + failed) + ' tests passed\n');
if (failed > 0) process.exit(1);
}
runAsyncTests();