blob: 0074060d0900ed57400f9df537e6d12314982496 [file] [log] [blame]
Leo Repp58b9f112021-11-22 11:57:47 +01001var tape = require('tape')
2var through = require('through2')
3var concat = require('concat-stream')
4var net = require('net')
5var duplexify = require('./')
6
7var HELLO_WORLD = (Buffer.from && Buffer.from !== Uint8Array.from)
8 ? Buffer.from('hello world')
9 : new Buffer('hello world')
10
11tape('passthrough', function(t) {
12 t.plan(2)
13
14 var pt = through()
15 var dup = duplexify(pt, pt)
16
17 dup.end('hello world')
18 dup.on('finish', function() {
19 t.ok(true, 'should finish')
20 })
21 dup.pipe(concat(function(data) {
22 t.same(data.toString(), 'hello world', 'same in as out')
23 }))
24})
25
26tape('passthrough + double end', function(t) {
27 t.plan(2)
28
29 var pt = through()
30 var dup = duplexify(pt, pt)
31
32 dup.end('hello world')
33 dup.end()
34
35 dup.on('finish', function() {
36 t.ok(true, 'should finish')
37 })
38 dup.pipe(concat(function(data) {
39 t.same(data.toString(), 'hello world', 'same in as out')
40 }))
41})
42
43tape('async passthrough + end', function(t) {
44 t.plan(2)
45
46 var pt = through.obj({highWaterMark:1}, function(data, enc, cb) {
47 setTimeout(function() {
48 cb(null, data)
49 }, 100)
50 })
51
52 var dup = duplexify(pt, pt)
53
54 dup.write('hello ')
55 dup.write('world')
56 dup.end()
57
58 dup.on('finish', function() {
59 t.ok(true, 'should finish')
60 })
61 dup.pipe(concat(function(data) {
62 t.same(data.toString(), 'hello world', 'same in as out')
63 }))
64})
65
66tape('duplex', function(t) {
67 var readExpected = ['read-a', 'read-b', 'read-c']
68 var writeExpected = ['write-a', 'write-b', 'write-c']
69
70 t.plan(readExpected.length+writeExpected.length+2)
71
72 var readable = through.obj()
73 var writable = through.obj(function(data, enc, cb) {
74 t.same(data, writeExpected.shift(), 'onwrite should match')
75 cb()
76 })
77
78 var dup = duplexify.obj(writable, readable)
79
80 readExpected.slice().forEach(function(data) {
81 readable.write(data)
82 })
83 readable.end()
84
85 writeExpected.slice().forEach(function(data) {
86 dup.write(data)
87 })
88 dup.end()
89
90 dup.on('data', function(data) {
91 t.same(data, readExpected.shift(), 'ondata should match')
92 })
93 dup.on('end', function() {
94 t.ok(true, 'should end')
95 })
96 dup.on('finish', function() {
97 t.ok(true, 'should finish')
98 })
99})
100
101tape('async', function(t) {
102 var dup = duplexify()
103 var pt = through()
104
105 dup.pipe(concat(function(data) {
106 t.same(data.toString(), 'i was async', 'same in as out')
107 t.end()
108 }))
109
110 dup.write('i')
111 dup.write(' was ')
112 dup.end('async')
113
114 setTimeout(function() {
115 dup.setWritable(pt)
116 setTimeout(function() {
117 dup.setReadable(pt)
118 }, 50)
119 }, 50)
120})
121
122tape('destroy', function(t) {
123 t.plan(2)
124
125 var write = through()
126 var read = through()
127 var dup = duplexify(write, read)
128
129 write.destroy = function() {
130 t.ok(true, 'write destroyed')
131 }
132
133 dup.on('close', function() {
134 t.ok(true, 'close emitted')
135 })
136
137 dup.destroy()
138 dup.destroy() // should only work once
139})
140
141tape('destroy both', function(t) {
142 t.plan(3)
143
144 var write = through()
145 var read = through()
146 var dup = duplexify(write, read)
147
148 write.destroy = function() {
149 t.ok(true, 'write destroyed')
150 }
151
152 read.destroy = function() {
153 t.ok(true, 'read destroyed')
154 }
155
156 dup.on('close', function() {
157 t.ok(true, 'close emitted')
158 })
159
160 dup.destroy()
161 dup.destroy() // should only work once
162})
163
164tape('bubble read errors', function(t) {
165 t.plan(2)
166
167 var write = through()
168 var read = through()
169 var dup = duplexify(write, read)
170
171 dup.on('error', function(err) {
172 t.same(err.message, 'read-error', 'received read error')
173 })
174 dup.on('close', function() {
175 t.ok(true, 'close emitted')
176 })
177
178 read.emit('error', new Error('read-error'))
179 write.emit('error', new Error('write-error')) // only emit first error
180})
181
182tape('bubble write errors', function(t) {
183 t.plan(2)
184
185 var write = through()
186 var read = through()
187 var dup = duplexify(write, read)
188
189 dup.on('error', function(err) {
190 t.same(err.message, 'write-error', 'received write error')
191 })
192 dup.on('close', function() {
193 t.ok(true, 'close emitted')
194 })
195
196 write.emit('error', new Error('write-error'))
197 read.emit('error', new Error('read-error')) // only emit first error
198})
199
200tape('reset writable / readable', function(t) {
201 t.plan(3)
202
203 var toUpperCase = function(data, enc, cb) {
204 cb(null, data.toString().toUpperCase())
205 }
206
207 var passthrough = through()
208 var upper = through(toUpperCase)
209 var dup = duplexify(passthrough, passthrough)
210
211 dup.once('data', function(data) {
212 t.same(data.toString(), 'hello')
213 dup.setWritable(upper)
214 dup.setReadable(upper)
215 dup.once('data', function(data) {
216 t.same(data.toString(), 'HELLO')
217 dup.once('data', function(data) {
218 t.same(data.toString(), 'HI')
219 t.end()
220 })
221 })
222 dup.write('hello')
223 dup.write('hi')
224 })
225 dup.write('hello')
226})
227
228tape('cork', function(t) {
229 var passthrough = through()
230 var dup = duplexify(passthrough, passthrough)
231 var ok = false
232
233 dup.on('prefinish', function() {
234 dup.cork()
235 setTimeout(function() {
236 ok = true
237 dup.uncork()
238 }, 100)
239 })
240 dup.on('finish', function() {
241 t.ok(ok)
242 t.end()
243 })
244 dup.end()
245})
246
247tape('prefinish not twice', function(t) {
248 var passthrough = through()
249 var dup = duplexify(passthrough, passthrough)
250 var prefinished = false
251
252 dup.on('prefinish', function() {
253 t.ok(!prefinished, 'only prefinish once')
254 prefinished = true
255 })
256
257 dup.on('finish', function() {
258 t.end()
259 })
260
261 dup.end()
262})
263
264tape('close', function(t) {
265 var passthrough = through()
266 var dup = duplexify(passthrough, passthrough)
267
268 passthrough.emit('close')
269 dup.on('close', function() {
270 t.ok(true, 'should forward close')
271 t.end()
272 })
273})
274
275tape('works with node native streams (net)', function(t) {
276 t.plan(1)
277
278 var server = net.createServer(function(socket) {
279 var dup = duplexify(socket, socket)
280
281 dup.once('data', function(chunk) {
282 t.same(chunk, HELLO_WORLD)
283 server.close()
284 socket.end()
285 t.end()
286 })
287 })
288
289 server.listen(0, function () {
290 var socket = net.connect(server.address().port)
291 var dup = duplexify(socket, socket)
292
293 dup.write(HELLO_WORLD)
294 })
295})