mirror of
https://github.com/coder/code-server.git
synced 2024-12-04 23:03:06 +08:00
eae5d8c807
These conflicts will be resolved in the following commits. We do it this way so that PR review is possible.
280 lines
6.9 KiB
JavaScript
280 lines
6.9 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*/
|
|
|
|
(function() {
|
|
const fs = require('fs');
|
|
const originals = {};
|
|
let logging = false;
|
|
let withStacks = false;
|
|
|
|
self.beginLoggingFS = (_withStacks) => {
|
|
logging = true;
|
|
withStacks = _withStacks || false;
|
|
};
|
|
self.endLoggingFS = () => {
|
|
logging = false;
|
|
withStacks = false;
|
|
};
|
|
|
|
function createSpy(element, cnt) {
|
|
return function(...args) {
|
|
if (logging) {
|
|
console.log(`calling ${element}: ` + args.slice(0, cnt).join(',') + (withStacks ? (`\n` + new Error().stack.split('\n').slice(2).join('\n')) : ''));
|
|
}
|
|
return originals[element].call(this, ...args);
|
|
};
|
|
}
|
|
|
|
function intercept(element, cnt) {
|
|
originals[element] = fs[element];
|
|
fs[element] = createSpy(element, cnt);
|
|
}
|
|
|
|
[
|
|
['realpathSync', 1],
|
|
['readFileSync', 1],
|
|
['openSync', 3],
|
|
['readSync', 1],
|
|
['closeSync', 1],
|
|
['readFile', 2],
|
|
['mkdir', 1],
|
|
['lstat', 1],
|
|
['stat', 1],
|
|
['watch', 1],
|
|
['readdir', 1],
|
|
['access', 2],
|
|
['open', 2],
|
|
['write', 1],
|
|
['fdatasync', 1],
|
|
['close', 1],
|
|
['read', 1],
|
|
['unlink', 1],
|
|
['rmdir', 1],
|
|
].forEach((element) => {
|
|
intercept(element[0], element[1]);
|
|
})
|
|
})();
|
|
|
|
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(),
|
|
titlePath: suite.titlePath(),
|
|
timeout: suite.timeout(),
|
|
retries: suite.retries(),
|
|
slow: suite.slow(),
|
|
bail: suite.bail()
|
|
};
|
|
}
|
|
|
|
function serializeRunnable(runnable) {
|
|
return {
|
|
title: runnable.title,
|
|
fullTitle: runnable.fullTitle(),
|
|
titlePath: runnable.titlePath(),
|
|
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);
|
|
});
|
|
});
|