Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node (Gulp) process.stdout.write to file

I'm trying to have gulp taking care of my unit tests for me, and outputting my test coverage to a .lcov file.

This is what I have so far :

gulp.task('test', function () {
    var test = fs.createWriteStream('./test.lcov', {flags: 'a'});
    return gulp.src('./assets/js/test/test.js', {read: false})
        .pipe(mocha({reporter: 'mocha-lcov-reporter'}))
        .pipe(test);
});

The mocha-lcov-reporter code can be found here : https://github.com/StevenLooman/mocha-lcov-reporter/blob/master/lib/lcov.js

It outputs results through process.stdout.write()

But when I pipe this to a WriteStream I have the following error :

TypeError: Invalid non-string/buffer chunk
    at validChunk (_stream_writable.js:152:14)
    at WriteStream.Writable.write (_stream_writable.js:181:12)
    at Stream.ondata (stream.js:51:26)
    at Stream.emit (events.js:95:17)
    at drain (/Users/braunromain/Documents/dev/should-i-go/node_modules/gulp-mocha/node_modules/through/index.js:36:16)
    at Stream.stream.queue.stream.push (/Users/braunromain/Documents/dev/should-i-go/node_modules/gulp-mocha/node_modules/through/index.js:45:5)
    at Stream.stream (/Users/braunromain/Documents/dev/should-i-go/node_modules/gulp-mocha/index.js:27:8)
    at Stream.stream.write (/Users/braunromain/Documents/dev/should-i-go/node_modules/gulp-mocha/node_modules/through/index.js:26:11)
    at write (/Users/braunromain/Documents/dev/should-i-go/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:623:24)
    at flow (/Users/braunromain/Documents/dev/should-i-go/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:632:7)
like image 310
Romain Braun Avatar asked Oct 20 '22 00:10

Romain Braun


1 Answers

Looks like gulp-mocha isn't totally set up to be a true through stream, in fact it looks like it just pipes the source into a Mocha instance and lets Mocha do it's thing.

The first thing that comes to my head just to do a simple redirect in bash...

$ gulp test | grep -Ev "^\[[0-9:]{0,8}\]" > ./test.lcov

Of course this assumes all the output that is gulp related will start with [00:00:00] (with the 00 being the current system time). If this isn't the case you may end up with gulp output at the top and bottom of your file.

If you're looking for a more universal answer (read: using nodejs) you can do a rewrite of process.stdout.write. This is probably :( upon by most but it would work. The trick is that you can't overwrite process.stdout as another stream because it is written as a getter internally. You can however rewrite the stdout.write function. As a matter of fact I just did this for a project I'm working on so I can review gulp logs of other developers in case they have issues with the build system.

I chose to go with a not so async solution because unlike most everything else in nodejs, stdout and stderr are both blocking streams and don't act like the asynchronous code you're used to. Using this technique your task would end up looking something like this:

gulp.task('test', function () {
  // clear out old coverage file
  fs.writeFileSync('./test.lcov', '');

  // if you still want to see output in the console
  //   you need a copy of the original write function
  var ogWrite = process.stdout.write;

  process.stdout.write = function( chunk ){
    fs.appendFile( './test.lcov', chunk );

    // this will write the output to the console
    ogWrite.apply( this, arguments );
  };

  return gulp.src('./assets/js/test/test.js', {read: false})
    .pipe(mocha({reporter: 'mocha-lcov-reporter'}));
});
like image 98
ashwell Avatar answered Oct 27 '22 21:10

ashwell