123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- 'use strict';
- require('./lib/worker/load-chalk'); // eslint-disable-line import/no-unassigned-import
- // 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.
- const path = require('path');
- const meow = require('meow');
- const Promise = require('bluebird');
- const uniqueTempDir = require('unique-temp-dir');
- const arrify = require('arrify');
- const resolveCwd = require('resolve-cwd');
- const babelPipeline = require('./lib/babel-pipeline');
- const RunStatus = require('./lib/run-status');
- const VerboseReporter = require('./lib/reporters/verbose');
- const loadConfig = require('./lib/load-config');
- function resolveModules(modules) {
- return arrify(modules).map(name => {
- const modulePath = resolveCwd.silent(name);
- if (modulePath === null) {
- throw new Error(`Could not resolve required module '${name}'`);
- }
- return modulePath;
- });
- }
- Promise.longStackTraces();
- const conf = loadConfig({
- babel: {
- testOptions: {}
- },
- compileEnhancements: true
- });
- const {projectDir} = conf;
- // Define a minimal set of options from the main CLI
- const cli = meow(`
- Usage
- $ iron-node node_modules/ava/profile.js <test-file>
- Options
- --fail-fast Stop after first test failure
- --serial, -s Run tests serially
- `, {
- string: [
- '_'
- ],
- boolean: [
- 'fail-fast',
- 'verbose',
- 'serial',
- 'tap'
- ],
- default: conf,
- alias: {
- s: 'serial'
- }
- });
- if (cli.input.length === 0) {
- throw new Error('Specify a test file');
- }
- const file = path.resolve(cli.input[0]);
- const cacheDir = conf.cacheEnabled === false ? uniqueTempDir() : path.join(projectDir, 'node_modules', '.cache', 'ava');
- const precompileFile = babelPipeline.build(process.cwd(), cacheDir, babelPipeline.validate(conf.babel), conf.compileEnhancements === true);
- const precompiled = {};
- if (precompileFile) {
- precompiled[file] = precompileFile(file);
- }
- const opts = {
- file,
- failFast: cli.flags.failFast,
- serial: cli.flags.serial,
- tty: false,
- cacheDir,
- precompiled,
- require: resolveModules(conf.require)
- };
- // Mock the behavior of a parent process
- process.connected = true;
- process.channel = {ref() {}, unref() {}};
- const reporter = new VerboseReporter({
- reportStream: process.stdout,
- stdStream: process.stderr,
- watching: false
- });
- const runStatus = new RunStatus([file]);
- runStatus.observeWorker({
- file,
- onStateChange(listener) {
- const emit = evt => listener(Object.assign(evt, {testFile: file}));
- process.send = data => {
- if (data && data.ava) {
- const evt = data.ava;
- if (evt.type === 'ping') {
- if (console.profileEnd) {
- console.profileEnd();
- }
- if (process.exitCode) {
- emit({type: 'worker-failed', nonZeroExitCode: process.exitCode});
- } else {
- emit({type: 'worker-finished', forcedExit: false});
- process.exitCode = runStatus.suggestExitCode({matching: false});
- }
- setImmediate(() => {
- reporter.endRun();
- process.emit('message', {ava: {type: 'pong'}});
- });
- } else {
- emit(data.ava);
- }
- }
- };
- }
- }, file);
- reporter.startRun({
- failFastEnabled: false,
- files: [file],
- matching: false,
- previousFailures: 0,
- status: runStatus
- });
- process.on('beforeExit', () => {
- process.exitCode = process.exitCode || runStatus.suggestExitCode({matching: false});
- });
- // The "subprocess" will read process.argv[2] for options
- process.argv[2] = JSON.stringify(opts);
- process.argv.length = 3;
- if (console.profile) {
- console.profile('AVA test-worker process');
- }
- setImmediate(() => {
- require('./lib/worker/subprocess'); // eslint-disable-line import/no-unassigned-import
- });
|