Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't emit end while waiting for pipes to clear #507

Merged
merged 4 commits into from
Feb 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions lib/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,26 @@ class Base extends MiniPass {
this.options.failures = failures

this.onbeforeend()
this.emit('end')
this.ondone()
// if we're piping, and buffered, then it means we need to hold off
// on emitting 'end' and calling ondone() until the pipes clear out.
if (this.pipes.length && this.buffer.length)
super.end()
else
this.emit('end')
}

onbeforeend () {}
ondone () {}

emit (ev, data) {
if (ev === 'end') {
const ret = super.emit(ev, data)
this.ondone()
return ret
} else
return super.emit(ev, data)
}

setupParser (options) {
this.parser = new Parser({
bail: this.bail,
Expand Down
26 changes: 26 additions & 0 deletions test/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,29 @@ t.test('oncomplete', t => {
b.parser.end(c[0])
}), c[2])))
})

t.test('pipes backing up', t => {
const MiniPass = require('minipass')
const mp = new MiniPass({ encoding: 'utf8' })
const b = new Base({})
b.pipe(mp)
let flushed = false
let ended = false
b.on('end', () => {
t.notOk(flushed, 'not ending before flushing the stream')
t.notOk(ended, 'not ended more than once')
ended = true
})
const tapdata = 'TAP version 13\n1..1\nok\n'
b.parser.end(tapdata)
setTimeout(() => {
let data = ''
let c = ''
while (c = mp.read()) data += c
flushed = true
t.equal(data, tapdata)
// pipes should have flushed now
t.ok(ended, 'ended')
t.end()
})
})
10 changes: 10 additions & 0 deletions test/regression-pipe-backup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict'

// https://github.com/tapjs/node-tap/pull/506

const t = require('../')

t.plan(5000)
for (let i = 1; i <= 5000; i++) {
t.pass(i)
}