Skip to content

Commit fea2208

Browse files
Benjamin Paseroalexdima
andauthored
Run unit tests against node.js too (microsoft#137790)
* tests - run unit tests also against node.js * fixes * fail if major node.js version mismatch * -tfs is unsupported * Add `@ts-check` and remove `jsdom` * tests - process.env layer breaker * Improve loader config * skip one test * address todos * try to force color output * Use a file: URI as baseUrl Co-authored-by: Alex Dima <alexdima@microsoft.com>
1 parent efaefaf commit fea2208

4 files changed

Lines changed: 69 additions & 129 deletions

File tree

unit/node/browser.js

Lines changed: 0 additions & 49 deletions
This file was deleted.

unit/node/css.mock.js

Lines changed: 0 additions & 12 deletions
This file was deleted.

unit/node/index.html

Lines changed: 0 additions & 30 deletions
This file was deleted.

unit/node/all.js renamed to unit/node/index.js

Lines changed: 69 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,37 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
/*eslint-env mocha*/
7-
/*global define,run*/
6+
//@ts-check
7+
8+
process.env.MOCHA_COLORS = '1'; // Force colors (note that this must come before any mocha imports)
89

910
const assert = require('assert');
11+
const mocha = require('mocha');
1012
const path = require('path');
13+
const fs = require('fs');
1114
const glob = require('glob');
12-
const jsdom = require('jsdom-no-contextify');
1315
const minimatch = require('minimatch');
1416
const coverage = require('../coverage');
1517
const optimist = require('optimist')
1618
.usage('Run the Code tests. All mocha options apply.')
1719
.describe('build', 'Run from out-build').boolean('build')
1820
.describe('run', 'Run a single file').string('run')
1921
.describe('coverage', 'Generate a coverage report').boolean('coverage')
20-
.describe('browser', 'Run tests in a browser').boolean('browser')
2122
.alias('h', 'help').boolean('h')
2223
.describe('h', 'Show help');
2324

25+
2426
const TEST_GLOB = '**/test/**/*.test.js';
2527
const excludeGlob = '**/{browser,electron-sandbox,electron-browser,electron-main,editor/contrib}/**/*.test.js';
26-
28+
const excludeModules = [
29+
'vs/platform/environment/test/node/nativeModules.test.js',
30+
'vs/base/parts/storage/test/node/storage.test.js',
31+
'vs/platform/files/test/common/files.test.js' // TODO@bpasero enable once we ship Electron 16
32+
]
33+
34+
/**
35+
* @type {{ build: boolean; run: string; runGlob: string; coverage: boolean; help: boolean; }}
36+
*/
2737
const argv = optimist.argv;
2838

2939
if (argv.help) {
@@ -36,21 +46,54 @@ const out = argv.build ? 'out-build' : 'out';
3646
const loader = require(`../../../${out}/vs/loader`);
3747
const src = path.join(REPO_ROOT, out);
3848

49+
const majorRequiredNodeVersion = `v${/^target\s+"([^"]+)"$/m.exec(fs.readFileSync(path.join(REPO_ROOT, 'remote', '.yarnrc'), 'utf8'))[1]}`.substring(0, 3);
50+
const currentMajorNodeVersion = process.version.substring(0, 3);
51+
if (majorRequiredNodeVersion !== currentMajorNodeVersion) {
52+
console.error(`node.js unit tests require a major node.js version of ${majorRequiredNodeVersion} (your version is: ${currentMajorNodeVersion})`);
53+
process.exit(1);
54+
}
55+
3956
function main() {
4057
process.on('uncaughtException', function (e) {
4158
console.error(e.stack || e);
4259
});
4360

61+
/**
62+
* @param {string} path
63+
* @param {{ isWindows?: boolean, scheme?: string, fallbackAuthority?: string }} config
64+
* @returns {string}
65+
*/
66+
function fileUriFromPath(path, config) {
67+
68+
// Since we are building a URI, we normalize any backslash
69+
// to slashes and we ensure that the path begins with a '/'.
70+
let pathName = path.replace(/\\/g, '/');
71+
if (pathName.length > 0 && pathName.charAt(0) !== '/') {
72+
pathName = `/${pathName}`;
73+
}
74+
75+
/** @type {string} */
76+
let uri;
77+
78+
// Windows: in order to support UNC paths (which start with '//')
79+
// that have their own authority, we do not use the provided authority
80+
// but rather preserve it.
81+
if (config.isWindows && pathName.startsWith('//')) {
82+
uri = encodeURI(`${config.scheme || 'file'}:${pathName}`);
83+
}
84+
85+
// Otherwise we optionally add the provided authority if specified
86+
else {
87+
uri = encodeURI(`${config.scheme || 'file'}://${config.fallbackAuthority || ''}${pathName}`);
88+
}
89+
90+
return uri.replace(/#/g, '%23');
91+
}
92+
4493
const loaderConfig = {
4594
nodeRequire: require,
4695
nodeMain: __filename,
47-
baseUrl: path.join(REPO_ROOT, 'src'),
48-
paths: {
49-
'vs/css': '../test/unit/node/css.mock',
50-
'vs': `../${out}/vs`,
51-
'lib': `../${out}/lib`,
52-
'bootstrap-fork': `../${out}/bootstrap-fork`
53-
},
96+
baseUrl: fileUriFromPath(src, { isWindows: process.platform === 'win32' }),
5497
catchError: true
5598
};
5699

@@ -67,36 +110,27 @@ function main() {
67110

68111
loader.config(loaderConfig);
69112

70-
global.define = loader;
71-
global.document = jsdom.jsdom('<!doctype html><html><body></body></html>');
72-
global.self = global.window = global.document.parentWindow;
73-
74-
global.Element = global.window.Element;
75-
global.HTMLElement = global.window.HTMLElement;
76-
global.Node = global.window.Node;
77-
global.navigator = global.window.navigator;
78-
global.XMLHttpRequest = global.window.XMLHttpRequest;
79-
80113
let didErr = false;
81114
const write = process.stderr.write;
82-
process.stderr.write = function (data) {
83-
didErr = didErr || !!data;
84-
write.apply(process.stderr, arguments);
115+
process.stderr.write = function (...args) {
116+
didErr = didErr || !!args[0];
117+
return write.apply(process.stderr, args);
85118
};
86119

120+
/** @type { (callback:(err:any)=>void)=>void } */
87121
let loadFunc = null;
88122

89123
if (argv.runGlob) {
90124
loadFunc = (cb) => {
91-
const doRun = tests => {
125+
const doRun = /** @param {string[]} tests */(tests) => {
92126
const modulesToLoad = tests.map(test => {
93127
if (path.isAbsolute(test)) {
94128
test = path.relative(src, path.resolve(test));
95129
}
96130

97131
return test.replace(/(\.js)|(\.d\.ts)|(\.js\.map)$/, '');
98132
});
99-
define(modulesToLoad, () => cb(null), cb);
133+
loader(modulesToLoad, () => cb(null), cb);
100134
};
101135

102136
glob(argv.runGlob, { cwd: src }, function (err, files) { doRun(files); });
@@ -109,18 +143,19 @@ function main() {
109143
return path.relative(src, path.resolve(test)).replace(/(\.js)|(\.js\.map)$/, '').replace(/\\/g, '/');
110144
});
111145
loadFunc = (cb) => {
112-
define(modulesToLoad, () => cb(null), cb);
146+
loader(modulesToLoad, () => cb(null), cb);
113147
};
114148
} else {
115149
loadFunc = (cb) => {
116150
glob(TEST_GLOB, { cwd: src }, function (err, files) {
151+
/** @type {string[]} */
117152
const modules = [];
118153
for (let file of files) {
119-
if (!minimatch(file, excludeGlob)) {
154+
if (!minimatch(file, excludeGlob) && excludeModules.indexOf(file) === -1) {
120155
modules.push(file.replace(/\.js$/, ''));
121156
}
122157
}
123-
define(modules, function () { cb(null); }, cb);
158+
loader(modules, function () { cb(null); }, cb);
124159
});
125160
};
126161
}
@@ -135,7 +170,7 @@ function main() {
135170

136171
if (!argv.run && !argv.runGlob) {
137172
// set up last test
138-
suite('Loader', function () {
173+
mocha.suite('Loader', function () {
139174
test('should not explode while loading', function () {
140175
assert.ok(!didErr, 'should not explode while loading');
141176
});
@@ -144,7 +179,7 @@ function main() {
144179

145180
// report failing test for every unexpected error during any of the tests
146181
let unexpectedErrors = [];
147-
suite('Errors', function () {
182+
mocha.suite('Errors', function () {
148183
test('should not have unexpected errors in tests', function () {
149184
if (unexpectedErrors.length) {
150185
unexpectedErrors.forEach(function (stack) {
@@ -165,13 +200,9 @@ function main() {
165200
});
166201

167202
// fire up mocha
168-
run();
203+
mocha.run();
169204
});
170205
});
171206
}
172207

173-
if (process.argv.some(function (a) { return /^--browser/.test(a); })) {
174-
require('./browser');
175-
} else {
176-
main();
177-
}
208+
main();

0 commit comments

Comments
 (0)