index.js 5.0 KB
Newer Older
J
Johannes Rieken 已提交
1 2 3 4 5 6 7 8
/*---------------------------------------------------------------------------------------------
 *  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');
9 10 11
const path = require('path');
const mocha = require('mocha');
const events = require('events');
J
Johannes Rieken 已提交
12

J
Joao Moreno 已提交
13 14
const defaultReporterName = process.platform === 'win32' ? 'list' : 'spec';

J
Johannes Rieken 已提交
15
const optimist = require('optimist')
J
Joao Moreno 已提交
16
	.describe('grep', 'only run tests matching <pattern>').alias('grep', 'g').alias('grep', 'f').string('grep')
J
Johannes Rieken 已提交
17
	.describe('run', 'only run tests from <file>').string('run')
J
Johannes Rieken 已提交
18
	.describe('runGlob', 'only run tests matching <file_pattern>').alias('runGlob', 'runGrep').string('runGlob')
19
	.describe('build', 'run with build output (out-build)').boolean('build')
J
Johannes Rieken 已提交
20
	.describe('coverage', 'generate coverage report').boolean('coverage')
J
Joao Moreno 已提交
21
	.describe('debug', 'open dev tools, keep window open, reuse app data').string('debug')
J
Joao Moreno 已提交
22 23 24
	.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').boolean('tfs')
J
Joao Moreno 已提交
25
	.describe('help', 'show the help').alias('help', 'h');
J
Johannes Rieken 已提交
26

J
Johannes Rieken 已提交
27
const argv = optimist.argv;
J
Johannes Rieken 已提交
28

J
Joao Moreno 已提交
29 30 31 32 33
if (argv.help) {
	optimist.showHelp();
	process.exit(0);
}

J
Johannes Rieken 已提交
34
if (!argv.debug) {
35 36
	app.setPath('userData', join(tmpdir(), `vscode-tests-${Date.now()}`));
}
J
Johannes Rieken 已提交
37

38 39
function deserializeSuite(suite) {
	return {
J
Joao Moreno 已提交
40 41 42
		root: suite.root,
		suites: suite.suites,
		tests: suite.tests,
43 44 45 46 47 48
		title: suite.title,
		fullTitle: () => suite.fullTitle,
		timeout: () => suite.timeout,
		retries: () => suite.retries,
		enableTimeouts: () => suite.enableTimeouts,
		slow: () => suite.slow,
T
thomas 已提交
49
		bail: () => suite.bail
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
	};
}

function deserializeRunnable(runnable) {
	return {
		title: runnable.title,
		fullTitle: () => runnable.fullTitle,
		async: runnable.async,
		slow: () => runnable.slow,
		speed: runnable.speed,
		duration: runnable.duration
	};
}

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)));
	}
}

J
Joao Moreno 已提交
94 95 96 97 98
function parseReporterOption(value) {
	let r = /^([^=]+)=(.*)$/.exec(value);
	return r ? { [r[1]]: r[2] } : {};
}

J
Johannes Rieken 已提交
99 100 101 102 103
app.on('ready', () => {

	const win = new BrowserWindow({
		height: 600,
		width: 800,
104
		show: false,
105 106 107 108
		webPreferences: {
			backgroundThrottling: false,
			webSecurity: false
		}
J
Johannes Rieken 已提交
109 110 111
	});

	win.webContents.on('did-finish-load', () => {
J
Johannes Rieken 已提交
112
		if (argv.debug) {
113
			win.show();
J
Johannes Rieken 已提交
114 115
			win.webContents.openDevTools('right');
		}
J
Johannes Rieken 已提交
116
		win.webContents.send('run', argv);
J
Johannes Rieken 已提交
117 118
	});

J
Johannes Rieken 已提交
119
	win.loadURL(`file://${__dirname}/renderer.html`);
J
Johannes Rieken 已提交
120

J
Joao Moreno 已提交
121
	const runner = new IPCRunner();
J
Johannes Rieken 已提交
122

J
Joao Moreno 已提交
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
	if (argv.tfs) {
		const Reporter = require('mocha-multi-reporters');
		const reporterOptions = {
			reporterEnabled: `${defaultReporterName}, mocha-junit-reporter`,
			mochaJunitReporterReporterOptions: {
				mochaFile: '.build/tests/unit-test-results.xml'
			}
		};

		new Reporter(runner, { reporterOptions });
	} 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}`);
			}
		}
J
Johannes Rieken 已提交
147

J
Joao Moreno 已提交
148 149 150 151 152 153
		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 });
	}
J
Johannes Rieken 已提交
154

155 156 157
	if (!argv.debug) {
		ipcMain.on('all done', () => app.exit(runner.didFail ? 1 : 0));
	}
J
Johannes Rieken 已提交
158
});