/ node_modules / split2 / test.js
test.js
  1  'use strict'
  2  
  3  const test = require('tape')
  4  const split = require('./')
  5  const callback = require('callback-stream')
  6  const strcb = callback.bind(null, { decodeStrings: false })
  7  const objcb = callback.bind(null, { objectMode: true })
  8  
  9  test('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  
 22  test('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  
 37  test('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  
 53  test('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  
 68  test('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  
 81  test('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  
 94  test('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  
107  test('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  
125  test('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  
138  test('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  
151  test('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  
164  test('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  
177  test('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  
197  test('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  
215  test('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  
237  test('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  
254  test('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  
272  test('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  
286  test('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  
303  test('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  
316  test('readable highWaterMark', function (t) {
317    const input = split()
318    t.equal(input._readableState.highWaterMark, 16)
319    t.end()
320  })
321  
322  test('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  
335  test('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  
351  test("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  
365  test('mapper throws flush', function (t) {
366    t.plan(1)
367    const error = new Error()
368    const input = split(function () {
369      throw error
370    })
371  
372    input.on('error', (err, list) => {
373      t.same(err, error)
374    })
375    input.end('hello')
376  })
377  
378  test('mapper throws on transform', function (t) {
379    t.plan(1)
380  
381    const error = new Error()
382    const input = split(function (l) {
383      throw error
384    })
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  
394  test('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  })