-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathex6.test.js
More file actions
62 lines (51 loc) · 1.42 KB
/
ex6.test.js
File metadata and controls
62 lines (51 loc) · 1.42 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
'use strict';
const { pump } = require('./ex6');
function assert(condition, message) {
if (!condition) throw new Error(message || 'Assertion failed');
}
async function* makeIterable(chunks, signal) {
for (const c of chunks) {
if (signal.aborted) return;
yield c;
}
}
(async () => {
const ac = new AbortController();
const { signal } = ac;
const written = [];
let closed = 0;
let drains = 0;
let backpressureAt = 2;
const sink = {
write(chunk) {
written.push(chunk);
if (written.length === backpressureAt) return false;
return true;
},
drain() {
drains++;
// after drain, allow one more write before backpressure again
backpressureAt = backpressureAt + 2;
return Promise.resolve();
},
close() {
closed++;
}
};
const it = makeIterable([1,2,3,4,5,6], signal);
// Abort after 4 is written (deterministic via sink.write length check)
const originalWrite = sink.write.bind(sink);
sink.write = (chunk) => {
const ok = originalWrite(chunk);
if (written.length === 4) ac.abort();
return ok;
};
await pump(it, sink, { signal });
assert(drains >= 1, 'must respect backpressure and call drain');
assert(closed === 1, 'must close exactly once on abort');
assert(written.length === 4, 'must not write chunks after abort');
console.log('ex6 tests passed');
})().catch((err) => {
console.error(err);
process.exit(1);
});