From 946fec3fa2276d226d07fbc90597f6f123ee8266 Mon Sep 17 00:00:00 2001 From: James Talmage Date: Mon, 25 Jan 2016 23:54:29 -0500 Subject: [PATCH] Add a profile script. --- .iron-node.js | 10 +++++ profile.js | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 .iron-node.js create mode 100644 profile.js diff --git a/.iron-node.js b/.iron-node.js new file mode 100644 index 000000000..fe0582ca9 --- /dev/null +++ b/.iron-node.js @@ -0,0 +1,10 @@ +module.exports = { + "app": { + "openDevToolsDetached" : true, // DEFAULT=FALSE; opens the dev tools windows detached in an own window. + "hideMainWindow" : true, // DEFAULT=FALSE; hides the main window to show dev tools only. + }, + "workSpaceDirectory" : function(argv) { // determines the workspace directory for specific commandline applications. + return __dirname + } +}; + diff --git a/profile.js b/profile.js new file mode 100644 index 000000000..98972336c --- /dev/null +++ b/profile.js @@ -0,0 +1,102 @@ +'use strict'; + +// iron-node does not work with forked processes +// This cli command will run a single file in the current process. +// Intended to be used with iron-node for profiling purposes. + +var path = require('path'); +var meow = require('meow'); +var Promise = require('bluebird'); +var pkgConf = require('pkg-conf'); +var arrify = require('arrify'); +var findCacheDir = require('find-cache-dir'); +var uniqueTempDir = require('unique-temp-dir'); +var EventEmitter = require('events').EventEmitter; +var CachingPrecompiler = require('./lib/caching-precompiler'); +var globals = require('./lib/globals'); + +// Chrome gets upset when the `this` value is non-null for these functions. +globals.setTimeout = setTimeout.bind(null); +globals.clearTimeout = clearTimeout.bind(null); + +Promise.longStackTraces(); +var conf = pkgConf.sync('ava'); + +// Define a minimal set of options from the main CLI. +var cli = meow([ + 'usage: iron-node node_modules/ava/profile.js [options] TEST_FILE', + '', + 'Options', + ' --fail-fast Stop after first test failure', + ' --serial, -s Run tests serially', + ' --require, -r Module to preload (Can be repeated)', + '' +], { + string: [ + '_', + 'require' + ], + boolean: [ + 'fail-fast', + 'verbose', + 'serial', + 'tap' + ], + default: conf, + alias: { + r: 'require', + s: 'serial' + } +}); + +if (cli.input.length !== 1) { + throw new Error('no file'); +} + +var file = path.resolve(cli.input[0]); +var cacheDir = findCacheDir({name: 'ava', files: [file]}) || uniqueTempDir(); +var opts = { + file: file, + failFast: cli.flags.failFast, + serial: cli.flags.serial, + require: arrify(cli.flags.require), + tty: false, + cacheDir: cacheDir, + precompiled: new CachingPrecompiler(cacheDir).generateHashForFile(file) +}; + +var events = new EventEmitter(); + +// Mock the behavior of a parent process. +process.send = function (data) { + if (data && data.ava) { + var name = data.name.replace(/^ava-/, ''); + if (events.listenerCount(name)) { + events.emit(name, data.data); + } else { + console.log('UNHANDLED AVA EVENT: ', name, data.data); + } + return; + } + console.log('NON AVA EVENT: ', data); +}; + +events.on('test', function (data) { + console.log('TEST:', data.title, data.error); +}); + +events.on('results', function (data) { + console.log('RESULTS: ', data.stats); +}); + +events.on('stats', function () { + setImmediate(function () { + process.emit('ava-run'); + }); +}); + +// test-worker will read process.argv[2] for options +process.argv[2] = JSON.stringify(opts); +process.argv.length = 3; + +require('./lib/test-worker');