225 lines
5.7 KiB
JavaScript
225 lines
5.7 KiB
JavaScript
|
/*---------------------------------------------------------------------------------------------
|
||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||
|
*--------------------------------------------------------------------------------------------*/
|
||
|
|
||
|
/*eslint-env mocha*/
|
||
|
|
||
|
const { ipcRenderer } = require('electron');
|
||
|
const assert = require('assert');
|
||
|
const path = require('path');
|
||
|
const glob = require('glob');
|
||
|
const util = require('util');
|
||
|
const bootstrap = require('../../../src/bootstrap');
|
||
|
const coverage = require('../coverage');
|
||
|
|
||
|
// Disabled custom inspect. See #38847
|
||
|
if (util.inspect && util.inspect['defaultOptions']) {
|
||
|
util.inspect['defaultOptions'].customInspect = false;
|
||
|
}
|
||
|
|
||
|
let _tests_glob = '**/test/**/*.test.js';
|
||
|
let loader;
|
||
|
let _out;
|
||
|
|
||
|
function initLoader(opts) {
|
||
|
let outdir = opts.build ? 'out-build' : 'out';
|
||
|
_out = path.join(__dirname, `../../../${outdir}`);
|
||
|
|
||
|
// setup loader
|
||
|
loader = require(`${_out}/vs/loader`);
|
||
|
const loaderConfig = {
|
||
|
nodeRequire: require,
|
||
|
nodeMain: __filename,
|
||
|
catchError: true,
|
||
|
baseUrl: bootstrap.fileUriFromPath(path.join(__dirname, '../../../src'), { isWindows: process.platform === 'win32' }),
|
||
|
paths: {
|
||
|
'vs': `../${outdir}/vs`,
|
||
|
'lib': `../${outdir}/lib`,
|
||
|
'bootstrap-fork': `../${outdir}/bootstrap-fork`
|
||
|
}
|
||
|
};
|
||
|
|
||
|
if (opts.coverage) {
|
||
|
// initialize coverage if requested
|
||
|
coverage.initialize(loaderConfig);
|
||
|
}
|
||
|
|
||
|
loader.require.config(loaderConfig);
|
||
|
}
|
||
|
|
||
|
function createCoverageReport(opts) {
|
||
|
if (opts.coverage) {
|
||
|
return coverage.createReport(opts.run || opts.runGlob);
|
||
|
}
|
||
|
return Promise.resolve(undefined);
|
||
|
}
|
||
|
|
||
|
function loadTestModules(opts) {
|
||
|
|
||
|
if (opts.run) {
|
||
|
const files = Array.isArray(opts.run) ? opts.run : [opts.run];
|
||
|
const modules = files.map(file => {
|
||
|
file = file.replace(/^src/, 'out');
|
||
|
file = file.replace(/\.ts$/, '.js');
|
||
|
return path.relative(_out, file).replace(/\.js$/, '');
|
||
|
});
|
||
|
return new Promise((resolve, reject) => {
|
||
|
loader.require(modules, resolve, reject);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
const pattern = opts.runGlob || _tests_glob;
|
||
|
|
||
|
return new Promise((resolve, reject) => {
|
||
|
glob(pattern, { cwd: _out }, (err, files) => {
|
||
|
if (err) {
|
||
|
reject(err);
|
||
|
return;
|
||
|
}
|
||
|
const modules = files.map(file => file.replace(/\.js$/, ''));
|
||
|
resolve(modules);
|
||
|
});
|
||
|
}).then(modules => {
|
||
|
return new Promise((resolve, reject) => {
|
||
|
loader.require(modules, resolve, reject);
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function loadTests(opts) {
|
||
|
|
||
|
const _unexpectedErrors = [];
|
||
|
const _loaderErrors = [];
|
||
|
|
||
|
// collect loader errors
|
||
|
loader.require.config({
|
||
|
onError(err) {
|
||
|
_loaderErrors.push(err);
|
||
|
console.error(err);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// collect unexpected errors
|
||
|
loader.require(['vs/base/common/errors'], function (errors) {
|
||
|
errors.setUnexpectedErrorHandler(function (err) {
|
||
|
let stack = (err ? err.stack : null);
|
||
|
if (!stack) {
|
||
|
stack = new Error().stack;
|
||
|
}
|
||
|
|
||
|
_unexpectedErrors.push((err && err.message ? err.message : err) + '\n' + stack);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
return loadTestModules(opts).then(() => {
|
||
|
suite('Unexpected Errors & Loader Errors', function () {
|
||
|
test('should not have unexpected errors', function () {
|
||
|
const errors = _unexpectedErrors.concat(_loaderErrors);
|
||
|
if (errors.length) {
|
||
|
errors.forEach(function (stack) {
|
||
|
console.error('');
|
||
|
console.error(stack);
|
||
|
});
|
||
|
assert.ok(false, errors);
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function serializeSuite(suite) {
|
||
|
return {
|
||
|
root: suite.root,
|
||
|
suites: suite.suites.map(serializeSuite),
|
||
|
tests: suite.tests.map(serializeRunnable),
|
||
|
title: suite.title,
|
||
|
fullTitle: suite.fullTitle(),
|
||
|
timeout: suite.timeout(),
|
||
|
retries: suite.retries(),
|
||
|
enableTimeouts: suite.enableTimeouts(),
|
||
|
slow: suite.slow(),
|
||
|
bail: suite.bail()
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function serializeRunnable(runnable) {
|
||
|
return {
|
||
|
title: runnable.title,
|
||
|
fullTitle: runnable.fullTitle(),
|
||
|
async: runnable.async,
|
||
|
slow: runnable.slow(),
|
||
|
speed: runnable.speed,
|
||
|
duration: runnable.duration
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function serializeError(err) {
|
||
|
return {
|
||
|
message: err.message,
|
||
|
stack: err.stack,
|
||
|
actual: err.actual,
|
||
|
expected: err.expected,
|
||
|
uncaught: err.uncaught,
|
||
|
showDiff: err.showDiff,
|
||
|
inspect: typeof err.inspect === 'function' ? err.inspect() : ''
|
||
|
};
|
||
|
}
|
||
|
|
||
|
class IPCReporter {
|
||
|
|
||
|
constructor(runner) {
|
||
|
runner.on('start', () => ipcRenderer.send('start'));
|
||
|
runner.on('end', () => ipcRenderer.send('end'));
|
||
|
runner.on('suite', suite => ipcRenderer.send('suite', serializeSuite(suite)));
|
||
|
runner.on('suite end', suite => ipcRenderer.send('suite end', serializeSuite(suite)));
|
||
|
runner.on('test', test => ipcRenderer.send('test', serializeRunnable(test)));
|
||
|
runner.on('test end', test => ipcRenderer.send('test end', serializeRunnable(test)));
|
||
|
runner.on('hook', hook => ipcRenderer.send('hook', serializeRunnable(hook)));
|
||
|
runner.on('hook end', hook => ipcRenderer.send('hook end', serializeRunnable(hook)));
|
||
|
runner.on('pass', test => ipcRenderer.send('pass', serializeRunnable(test)));
|
||
|
runner.on('fail', (test, err) => ipcRenderer.send('fail', serializeRunnable(test), serializeError(err)));
|
||
|
runner.on('pending', test => ipcRenderer.send('pending', serializeRunnable(test)));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function runTests(opts) {
|
||
|
|
||
|
return loadTests(opts).then(() => {
|
||
|
|
||
|
if (opts.grep) {
|
||
|
mocha.grep(opts.grep);
|
||
|
}
|
||
|
|
||
|
if (!opts.debug) {
|
||
|
mocha.reporter(IPCReporter);
|
||
|
}
|
||
|
|
||
|
const runner = mocha.run(() => {
|
||
|
createCoverageReport(opts).then(() => {
|
||
|
ipcRenderer.send('all done');
|
||
|
});
|
||
|
});
|
||
|
|
||
|
if (opts.debug) {
|
||
|
runner.on('fail', (test, err) => {
|
||
|
|
||
|
console.error(test.fullTitle());
|
||
|
console.error(err.stack);
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
ipcRenderer.on('run', (e, opts) => {
|
||
|
initLoader(opts);
|
||
|
runTests(opts).catch(err => {
|
||
|
if (typeof err !== 'string') {
|
||
|
err = JSON.stringify(err);
|
||
|
}
|
||
|
|
||
|
console.error(err);
|
||
|
ipcRenderer.send('error', err);
|
||
|
});
|
||
|
});
|