UNPKG

4.18 kBJavaScriptView Raw
1'use strict';
2var opts = JSON.parse(process.argv[2]);
3var testPath = opts.file;
4
5// Fake TTY support
6if (opts.tty) {
7 process.stdout.isTTY = true;
8 process.stdout.columns = opts.tty.columns || 80;
9 process.stdout.rows = opts.tty.rows;
10
11 var tty = require('tty');
12 var isatty = tty.isatty;
13
14 tty.isatty = function (fd) {
15 if (fd === 1 || fd === process.stdout) {
16 return true;
17 }
18
19 return isatty(fd);
20 };
21}
22
23var path = require('path');
24var fs = require('fs');
25var debug = require('debug')('ava');
26var sourceMapSupport = require('source-map-support');
27
28if (debug.enabled) {
29 // Forward the `time-require` `--sorted` flag.
30 // Intended for internal optimization tests only.
31 if (opts._sorted) {
32 process.argv.push('--sorted');
33 }
34
35 require('time-require');
36}
37
38// bind globals first before anything has a chance to interfere
39var globals = require('./globals');
40globals.options = opts;
41var Promise = require('bluebird');
42
43// Bluebird specific
44Promise.longStackTraces();
45
46(opts.require || []).forEach(require);
47
48var sourceMapCache = Object.create(null);
49
50sourceMapSupport.install({
51 handleUncaughtExceptions: false,
52 retrieveSourceMap: function (source) {
53 if (sourceMapCache[source]) {
54 return {
55 url: source,
56 map: fs.readFileSync(sourceMapCache[source], 'utf8')
57 };
58 }
59 }
60});
61
62var loudRejection = require('loud-rejection/api')(process);
63var serializeError = require('serialize-error');
64var beautifyStack = require('./beautify-stack');
65var send = require('./send');
66var installPrecompiler = require('require-precompiled');
67var cacheDir = opts.cacheDir;
68
69// check if test files required ava and show error, when they didn't
70exports.avaRequired = false;
71
72installPrecompiler(function (filename) {
73 var precompiled = opts.precompiled[filename];
74
75 if (precompiled) {
76 sourceMapCache[filename] = path.join(cacheDir, precompiled + '.map');
77 return fs.readFileSync(path.join(cacheDir, precompiled + '.js'), 'utf8');
78 }
79
80 return null;
81});
82
83// Modules need to be able to find `babel-runtime`, which is nested in our node_modules w/ npm@2
84var nodeModulesDir = path.join(__dirname, '../node_modules');
85var oldNodeModulesPaths = module.constructor._nodeModulePaths;
86module.constructor._nodeModulePaths = function () {
87 var ret = oldNodeModulesPaths.apply(this, arguments);
88 ret.push(nodeModulesDir);
89 return ret;
90};
91
92var dependencies = [];
93Object.keys(require.extensions).forEach(function (ext) {
94 var wrappedHandler = require.extensions[ext];
95 require.extensions[ext] = function (module, filename) {
96 if (filename !== testPath) {
97 dependencies.push(filename);
98 }
99 wrappedHandler(module, filename);
100 };
101});
102
103require(testPath);
104
105process.on('uncaughtException', function (exception) {
106 var serialized = serializeError(exception);
107 if (serialized.stack) {
108 serialized.stack = beautifyStack(serialized.stack);
109 }
110 send('uncaughtException', {exception: serialized});
111});
112
113// if ava was not required, show an error
114if (!exports.avaRequired) {
115 send('no-tests', {avaRequired: false});
116}
117
118// parse and re-emit ava messages
119process.on('message', function (message) {
120 if (!message.ava) {
121 return;
122 }
123
124 process.emit(message.name, message.data);
125});
126
127process.on('ava-exit', function () {
128 // use a little delay when running on AppVeyor (because it's shit)
129 var delay = process.env.AVA_APPVEYOR ? 100 : 0;
130
131 globals.setTimeout(function () {
132 process.exit(0);
133 }, delay);
134});
135
136var tearingDown = false;
137process.on('ava-teardown', function () {
138 // ava-teardown can be sent more than once.
139 if (tearingDown) {
140 return;
141 }
142 tearingDown = true;
143
144 var rejections = loudRejection.currentlyUnhandled();
145
146 if (rejections.length === 0) {
147 exit();
148 return;
149 }
150
151 rejections = rejections.map(function (rejection) {
152 var error = serializeError(rejection.reason);
153 if (error.stack) {
154 error.stack = beautifyStack(error.stack);
155 }
156 return error;
157 });
158
159 send('unhandledRejections', {rejections: rejections});
160 globals.setTimeout(exit, 100);
161});
162
163function exit() {
164 // Include dependencies in the final teardown message. This ensures the full
165 // set of dependencies is included no matter how the process exits, unless
166 // it flat out crashes.
167 send('teardown', {dependencies: dependencies});
168}