UNPKG

@stdlib/bench-harness

Version:
190 lines (166 loc) 3.44 kB
/** * @license Apache-2.0 * * Copyright (c) 2018 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* eslint-disable no-underscore-dangle */ 'use strict'; // MODULES // var TransformStream = require( '@stdlib/streams-node-transform' ); var isString = require( '@stdlib/assert-is-string' ).isPrimitive; var nextTick = require( './../utils/next_tick.js' ); // VARIABLES // var TAP_HEADER = 'TAP version 13'; // MAIN // /** * Creates a results stream. * * @private * @param {Options} [options] - stream options * @throws {TypeError} options argument must be an object * @throws {TypeError} must provide valid options * @returns {TransformStream} transform stream */ function createStream( options ) { /* eslint-disable no-invalid-this */ var stream; var opts; var self; var id; self = this; if ( arguments.length ) { opts = options; } else { opts = {}; } stream = new TransformStream( opts ); if ( opts.objectMode ) { id = 0; this.on( '_push', onPush ); this.on( 'done', onDone ); } else { stream.write( TAP_HEADER+'\n' ); this._stream.pipe( stream ); } this.on( '_run', onRun ); return stream; /** * Runs the next benchmark. * * @private */ function next() { nextTick( onTick ); } /** * Callback invoked upon the next tick. * * @private * @returns {void} */ function onTick() { var b = self._benchmarks.shift(); if ( b ) { b.run(); if ( !b.ended() ) { return b.once( 'end', next ); } return next(); } self._running = false; self.emit( 'done' ); } /** * Callback invoked upon a run event. * * @private * @returns {void} */ function onRun() { if ( !self._running ) { self._running = true; return next(); } } /** * Callback invoked upon a push event. * * @private * @param {Benchmark} b - benchmark */ function onPush( b ) { var bid = id; id += 1; b.once( 'prerun', onPreRun ); b.on( 'result', onResult ); b.on( 'end', onEnd ); /** * Callback invoked upon a `prerun` event. * * @private */ function onPreRun() { var row = { 'type': 'benchmark', 'name': b.name, 'id': bid }; stream.write( row ); } /** * Callback invoked upon a `result` event. * * @private * @param {(Object|string)} res - result */ function onResult( res ) { if ( isString( res ) ) { res = { 'benchmark': bid, 'type': 'comment', 'name': res }; } else if ( res.operator === 'result' ) { res.benchmark = bid; res.type = 'result'; } else { res.benchmark = bid; res.type = 'assert'; } stream.write( res ); } /** * Callback invoked upon an `end` event. * * @private */ function onEnd() { stream.write({ 'benchmark': bid, 'type': 'end' }); } } /** * Callback invoked upon a `done` event. * * @private */ function onDone() { stream.destroy(); } } // EXPORTS // module.exports = createStream;