test.js 5.9 KB

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