tapjs/tap-parser

assert relies on stream end when plan line is at beginning

Closed this issue · 3 comments

3cp commented

A standard code copied from README, only added log on events "plan", "line" and "assert".

This is my pp.js

var Parser = require('tap-parser');
var p = new Parser(function (results) {
    console.dir(results);
});
p.on('plan', p => console.log('plan', p));
p.on('line', p => console.log('line', p));
p.on('assert', p => console.log('assert', p));
process.stdin.pipe(p);

If you cat a file to this program, it runs fine, but if you feed input from stdin line by line (manually by keyboard), you can see the "assert" strangely waits for stream end. I have this issue in my use case because my input stream never ends, and I need to use tap-parser "assert" event to understand TAP text.

> node pp.js
1..2
line 1..2

## this first plan line triggered "line" and "plan" correctly
plan { start: 1, end: 2 }
ok 1
## this first result line somehow only triggered "line" event.
line ok 1
ok 2
## somehow first "assert" is after tap-parser sees second result line.
assert Result { ok: true, id: 1, fullname: '' } 
line ok 2

## second "assert" event is never triggered even after
## following three lines.
# tests 2
# pass 2  
# fail 0

## I have to hit ctrl-D to end the stream for tap-parser
## to trigger last "assert" plus 3 more "line"
assert Result { ok: true, id: 2, fullname: '' }
line # tests 2

line # pass 2

line # fail 0

FinalResults {
  ok: true,
  count: 2,
  pass: 2,
  fail: 0,
  bailout: false,
  todo: 0,
  skip: 0,
  plan: FinalPlan {
    start: 1,
    end: 2,
    skipAll: false,
    skipReason: '',
    comment: ''
  },
  failures: []
}
3cp commented

Note, if plan line is after all result lines, tap-parser has no such issue.

The issue is that this is valid TAP:

TAP version 13
1..2
ok
ok
  ---
  some: diagnostics
  ...

And so is this:

TAP version 13
1..2
ok
ok
  ---
  some: diagnostics
  ...
{
    1..1
    ok - child assertion
}

And you can even put a comment right in the midst of all that jazz:

TAP version 13
1..2
ok
ok
  ---
  some: diagnostics
  ...
# nested child test coming!
{
    1..1
    ok - child assertion
# here it is! it's happening!
}

So, it has to wait until it finds something that is definitely the end of the assertion. Since diagnostics might be coming after the assertion line, it has to wait for that. Since a buffered child test might be coming after the diagnostics, it has to wait for that too.

It works when the plan comes at the end, because 1..2 is definitely not diagnostics, not a comment, and not a buffered child test.

Sorry, I think you're going to just have to figure out a way to end the stream when it's done.

3cp commented

Thanks for the details!