Archived
1
0

Squashed 'lib/vscode/' content from commit e5a624b788

git-subtree-dir: lib/vscode
git-subtree-split: e5a624b788d92b8d34d1392e4c4d9789406efe8f
This commit is contained in:
Joe Previte
2020-12-15 15:52:33 -07:00
commit be3e823608
4649 changed files with 1311795 additions and 0 deletions

175
test/unit/electron/index.js Normal file
View File

@ -0,0 +1,175 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const { app, BrowserWindow, ipcMain } = require('electron');
const { tmpdir } = require('os');
const { join } = require('path');
const path = require('path');
const mocha = require('mocha');
const events = require('events');
const MochaJUnitReporter = require('mocha-junit-reporter');
const url = require('url');
// Disable render process reuse, we still have
// non-context aware native modules in the renderer.
app.allowRendererProcessReuse = false;
const defaultReporterName = process.platform === 'win32' ? 'list' : 'spec';
const optimist = require('optimist')
.describe('grep', 'only run tests matching <pattern>').alias('grep', 'g').alias('grep', 'f').string('grep')
.describe('run', 'only run tests from <file>').string('run')
.describe('runGlob', 'only run tests matching <file_pattern>').alias('runGlob', 'glob').alias('runGlob', 'runGrep').string('runGlob')
.describe('build', 'run with build output (out-build)').boolean('build')
.describe('coverage', 'generate coverage report').boolean('coverage')
.describe('debug', 'open dev tools, keep window open, reuse app data').string('debug')
.describe('reporter', 'the mocha reporter').string('reporter').default('reporter', defaultReporterName)
.describe('reporter-options', 'the mocha reporter options').string('reporter-options').default('reporter-options', '')
.describe('tfs').string('tfs')
.describe('help', 'show the help').alias('help', 'h');
const argv = optimist.argv;
if (argv.help) {
optimist.showHelp();
process.exit(0);
}
if (!argv.debug) {
app.setPath('userData', join(tmpdir(), `vscode-tests-${Date.now()}`));
}
function deserializeSuite(suite) {
return {
root: suite.root,
suites: suite.suites,
tests: suite.tests,
title: suite.title,
fullTitle: () => suite.fullTitle,
timeout: () => suite.timeout,
retries: () => suite.retries,
enableTimeouts: () => suite.enableTimeouts,
slow: () => suite.slow,
bail: () => suite.bail
};
}
function deserializeRunnable(runnable) {
return {
title: runnable.title,
fullTitle: () => runnable.fullTitle,
async: runnable.async,
slow: () => runnable.slow,
speed: runnable.speed,
duration: runnable.duration,
currentRetry: () => runnable.currentRetry
};
}
function deserializeError(err) {
const inspect = err.inspect;
err.inspect = () => inspect;
return err;
}
class IPCRunner extends events.EventEmitter {
constructor() {
super();
this.didFail = false;
ipcMain.on('start', () => this.emit('start'));
ipcMain.on('end', () => this.emit('end'));
ipcMain.on('suite', (e, suite) => this.emit('suite', deserializeSuite(suite)));
ipcMain.on('suite end', (e, suite) => this.emit('suite end', deserializeSuite(suite)));
ipcMain.on('test', (e, test) => this.emit('test', deserializeRunnable(test)));
ipcMain.on('test end', (e, test) => this.emit('test end', deserializeRunnable(test)));
ipcMain.on('hook', (e, hook) => this.emit('hook', deserializeRunnable(hook)));
ipcMain.on('hook end', (e, hook) => this.emit('hook end', deserializeRunnable(hook)));
ipcMain.on('pass', (e, test) => this.emit('pass', deserializeRunnable(test)));
ipcMain.on('fail', (e, test, err) => {
this.didFail = true;
this.emit('fail', deserializeRunnable(test), deserializeError(err));
});
ipcMain.on('pending', (e, test) => this.emit('pending', deserializeRunnable(test)));
}
}
function parseReporterOption(value) {
let r = /^([^=]+)=(.*)$/.exec(value);
return r ? { [r[1]]: r[2] } : {};
}
app.on('ready', () => {
ipcMain.on('error', (_, err) => {
if (!argv.debug) {
console.error(err);
app.exit(1);
}
});
const win = new BrowserWindow({
height: 600,
width: 800,
show: false,
webPreferences: {
preload: path.join(__dirname, '..', '..', '..', 'src', 'vs', 'base', 'parts', 'sandbox', 'electron-browser', 'preload.js'), // ensure similar environment as VSCode as tests may depend on this
nodeIntegration: true,
enableWebSQL: false,
enableRemoteModule: false,
spellcheck: false,
nativeWindowOpen: true,
webviewTag: true
}
});
win.webContents.on('did-finish-load', () => {
if (argv.debug) {
win.show();
win.webContents.openDevTools();
}
win.webContents.send('run', argv);
});
win.loadURL(url.format({ pathname: path.join(__dirname, 'renderer.html'), protocol: 'file:', slashes: true }));
const runner = new IPCRunner();
if (argv.tfs) {
new mocha.reporters.Spec(runner);
new MochaJUnitReporter(runner, {
reporterOptions: {
testsuitesTitle: `${argv.tfs} ${process.platform}`,
mochaFile: process.env.BUILD_ARTIFACTSTAGINGDIRECTORY ? path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${process.arch}-${argv.tfs.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`) : undefined
}
});
} else {
const reporterPath = path.join(path.dirname(require.resolve('mocha')), 'lib', 'reporters', argv.reporter);
let Reporter;
try {
Reporter = require(reporterPath);
} catch (err) {
try {
Reporter = require(argv.reporter);
} catch (err) {
Reporter = process.platform === 'win32' ? mocha.reporters.List : mocha.reporters.Spec;
console.warn(`could not load reporter: ${argv.reporter}, using ${Reporter.name}`);
}
}
let reporterOptions = argv['reporter-options'];
reporterOptions = typeof reporterOptions === 'string' ? [reporterOptions] : reporterOptions;
reporterOptions = reporterOptions.reduce((r, o) => Object.assign(r, parseReporterOption(o)), {});
new Reporter(runner, { reporterOptions });
}
if (!argv.debug) {
ipcMain.on('all done', () => app.exit(runner.didFail ? 1 : 0));
}
});

View File

@ -0,0 +1,44 @@
<html>
<head>
<meta charset="utf-8">
<title>VSCode Tests</title>
<link href="../../../node_modules/mocha/mocha.css" rel="stylesheet" />
</head>
<body>
<div id="mocha"></div>
<script src="../../../node_modules/mocha/mocha.js"></script>
<script>
// !!! DO NOT CHANGE !!!
// Our unit tests may run in environments without
// display (e.g. from builds) and tests may by
// accident bring up native dialogs or even open
// windows. This we cannot allow as it may crash
// the test run.
// !!! DO NOT CHANGE !!!
window.open = function () { throw new Error('window.open() is not supported in tests!'); };
window.alert = function () { throw new Error('window.alert() is not supported in tests!'); }
window.confirm = function () { throw new Error('window.confirm() is not supported in tests!'); }
// Ignore uncaught cancelled promise errors
window.addEventListener('unhandledrejection', e => {
const name = e && e.reason && e.reason.name;
if (name === 'Canceled') {
e.preventDefault();
e.stopPropagation();
}
});
mocha.setup({
ui: 'tdd',
timeout: 5000
});
require('./renderer');
</script>
</body>
</html>

View File

@ -0,0 +1,224 @@
/*---------------------------------------------------------------------------------------------
* 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);
});
});