strong-tie/inbound-calls
0
1'use strict'2 3const test = require('tape')4const split = require('./')5const callback = require('callback-stream')6const strcb = callback.bind(null, { decodeStrings: false })7const objcb = callback.bind(null, { objectMode: true })8 9test('split two lines on end', function (t) {10 t.plan(2)11 12 const input = split()13 14 input.pipe(strcb(function (err, list) {15 t.error(err)16 t.deepEqual(list, ['hello', 'world'])17 }))18 19 input.end('hello\nworld')20})21 22test('split two lines on two writes', function (t) {23 t.plan(2)24 25 const input = split()26 27 input.pipe(strcb(function (err, list) {28 t.error(err)29 t.deepEqual(list, ['hello', 'world'])30 }))31 32 input.write('hello')33 input.write('\nworld')34 input.end()35})36 37test('split four lines on three writes', function (t) {38 t.plan(2)39 40 const input = split()41 42 input.pipe(strcb(function (err, list) {43 t.error(err)44 t.deepEqual(list, ['hello', 'world', 'bye', 'world'])45 }))46 47 input.write('hello\nwor')48 input.write('ld\nbye\nwo')49 input.write('rld')50 input.end()51})52 53test('accumulate multiple writes', function (t) {54 t.plan(2)55 56 const input = split()57 58 input.pipe(strcb(function (err, list) {59 t.error(err)60 t.deepEqual(list, ['helloworld'])61 }))62 63 input.write('hello')64 input.write('world')65 input.end()66})67 68test('split using a custom string matcher', function (t) {69 t.plan(2)70 71 const input = split('~')72 73 input.pipe(strcb(function (err, list) {74 t.error(err)75 t.deepEqual(list, ['hello', 'world'])76 }))77 78 input.end('hello~world')79})80 81test('split using a custom regexp matcher', function (t) {82 t.plan(2)83 84 const input = split(/~/)85 86 input.pipe(strcb(function (err, list) {87 t.error(err)88 t.deepEqual(list, ['hello', 'world'])89 }))90 91 input.end('hello~world')92})93 94test('support an option argument', function (t) {95 t.plan(2)96 97 const input = split({ highWaterMark: 2 })98 99 input.pipe(strcb(function (err, list) {100 t.error(err)101 t.deepEqual(list, ['hello', 'world'])102 }))103 104 input.end('hello\nworld')105})106 107test('support a mapper function', function (t) {108 t.plan(2)109 110 const a = { a: '42' }111 const b = { b: '24' }112 113 const input = split(JSON.parse)114 115 input.pipe(objcb(function (err, list) {116 t.error(err)117 t.deepEqual(list, [a, b])118 }))119 120 input.write(JSON.stringify(a))121 input.write('\n')122 input.end(JSON.stringify(b))123})124 125test('split lines windows-style', function (t) {126 t.plan(2)127 128 const input = split()129 130 input.pipe(strcb(function (err, list) {131 t.error(err)132 t.deepEqual(list, ['hello', 'world'])133 }))134 135 input.end('hello\r\nworld')136})137 138test('splits a buffer', function (t) {139 t.plan(2)140 141 const input = split()142 143 input.pipe(strcb(function (err, list) {144 t.error(err)145 t.deepEqual(list, ['hello', 'world'])146 }))147 148 input.end(Buffer.from('hello\nworld'))149})150 151test('do not end on undefined', function (t) {152 t.plan(2)153 154 const input = split(function (line) { })155 156 input.pipe(strcb(function (err, list) {157 t.error(err)158 t.deepEqual(list, [])159 }))160 161 input.end(Buffer.from('hello\nworld'))162})163 164test('has destroy method', function (t) {165 t.plan(1)166 167 const input = split(function (line) { })168 169 input.on('close', function () {170 t.ok(true, 'close emitted')171 t.end()172 })173 174 input.destroy()175})176 177test('support custom matcher and mapper', function (t) {178 t.plan(4)179 180 const a = { a: '42' }181 const b = { b: '24' }182 const input = split('~', JSON.parse)183 184 t.equal(input.matcher, '~')185 t.equal(typeof input.mapper, 'function')186 187 input.pipe(objcb(function (err, list) {188 t.notOk(err, 'no errors')189 t.deepEqual(list, [a, b])190 }))191 192 input.write(JSON.stringify(a))193 input.write('~')194 input.end(JSON.stringify(b))195})196 197test('support custom matcher and options', function (t) {198 t.plan(6)199 200 const input = split('~', { highWaterMark: 1024 })201 202 t.equal(input.matcher, '~')203 t.equal(typeof input.mapper, 'function')204 t.equal(input._readableState.highWaterMark, 1024)205 t.equal(input._writableState.highWaterMark, 1024)206 207 input.pipe(strcb(function (err, list) {208 t.error(err)209 t.deepEqual(list, ['hello', 'world'])210 }))211 212 input.end('hello~world')213})214 215test('support mapper and options', function (t) {216 t.plan(6)217 218 const a = { a: '42' }219 const b = { b: '24' }220 const input = split(JSON.parse, { highWaterMark: 1024 })221 222 t.ok(input.matcher instanceof RegExp, 'matcher is RegExp')223 t.equal(typeof input.mapper, 'function')224 t.equal(input._readableState.highWaterMark, 1024)225 t.equal(input._writableState.highWaterMark, 1024)226 227 input.pipe(objcb(function (err, list) {228 t.error(err)229 t.deepEqual(list, [a, b])230 }))231 232 input.write(JSON.stringify(a))233 input.write('\n')234 input.end(JSON.stringify(b))235})236 237test('split utf8 chars', function (t) {238 t.plan(2)239 240 const input = split()241 242 input.pipe(strcb(function (err, list) {243 t.error(err)244 t.deepEqual(list, ['烫烫烫', '锟斤拷'])245 }))246 247 const buf = Buffer.from('烫烫烫\r\n锟斤拷', 'utf8')248 for (let i = 0; i < buf.length; ++i) {249 input.write(buf.slice(i, i + 1))250 }251 input.end()252})253 254test('split utf8 chars 2by2', function (t) {255 t.plan(2)256 257 const input = split()258 259 input.pipe(strcb(function (err, list) {260 t.error(err)261 t.deepEqual(list, ['烫烫烫', '烫烫烫'])262 }))263 264 const str = '烫烫烫\r\n烫烫烫'265 const buf = Buffer.from(str, 'utf8')266 for (let i = 0; i < buf.length; i += 2) {267 input.write(buf.slice(i, i + 2))268 }269 input.end()270})271 272test('split lines when the \n comes at the end of a chunk', function (t) {273 t.plan(2)274 275 const input = split()276 277 input.pipe(strcb(function (err, list) {278 t.error(err)279 t.deepEqual(list, ['hello', 'world'])280 }))281 282 input.write('hello\n')283 input.end('world')284})285 286test('truncated utf-8 char', function (t) {287 t.plan(2)288 289 const input = split()290 291 input.pipe(strcb(function (err, list) {292 t.error(err)293 t.deepEqual(list, ['烫' + Buffer.from('e7', 'hex').toString()])294 }))295 296 const str = '烫烫'297 const buf = Buffer.from(str, 'utf8')298 299 input.write(buf.slice(0, 3))300 input.end(buf.slice(3, 4))301})302 303test('maximum buffer limit', function (t) {304 t.plan(1)305 306 const input = split({ maxLength: 2 })307 input.on('error', function (err) {308 t.ok(err)309 })310 311 input.resume()312 313 input.write('hey')314})315 316test('readable highWaterMark', function (t) {317 const input = split()318 t.equal(input._readableState.highWaterMark, 16)319 t.end()320})321 322test('maxLength < chunk size', function (t) {323 t.plan(2)324 325 const input = split({ maxLength: 2 })326 327 input.pipe(strcb(function (err, list) {328 t.error(err)329 t.deepEqual(list, ['a', 'b'])330 }))331 332 input.end('a\nb')333})334 335test('maximum buffer limit w/skip', function (t) {336 t.plan(2)337 338 const input = split({ maxLength: 2, skipOverflow: true })339 340 input.pipe(strcb(function (err, list) {341 t.error(err)342 t.deepEqual(list, ['a', 'b', 'c'])343 }))344 345 input.write('a\n123')346 input.write('456')347 input.write('789\nb\nc')348 input.end()349})350 351test("don't modify the options object", function (t) {352 t.plan(2)353 354 const options = {}355 const input = split(options)356 357 input.pipe(strcb(function (err, list) {358 t.error(err)359 t.same(options, {})360 }))361 362 input.end()363})364 365test('mapper throws flush', function (t) {366 t.plan(1)367 const error = new Error()368 const input = split(function () {369 throw error370 })371 372 input.on('error', (err, list) => {373 t.same(err, error)374 })375 input.end('hello')376})377 378test('mapper throws on transform', function (t) {379 t.plan(1)380 381 const error = new Error()382 const input = split(function (l) {383 throw error384 })385 386 input.on('error', (err) => {387 t.same(err, error)388 })389 input.write('a')390 input.write('\n')391 input.end('b')392})393 394test('supports Symbol.split', function (t) {395 t.plan(2)396 397 const input = split({398 [Symbol.split] (str) {399 return str.split('~')400 }401 })402 403 input.pipe(strcb(function (err, list) {404 t.error(err)405 t.deepEqual(list, ['hello', 'world'])406 }))407 408 input.end('hello~world')409})410 