TypeScript/scripts/mocha-parallel.js
Yui f235bf7db8 [Transforms] Merge master 06/06/2016 (#8991)
* Remove check narrowing only certain types, add test showing issues with this

* string literal case test

* Reconcile fix with CFA work

* Defaultable -> NotNarrowable to align with use

* Missed a defaultable in comments

* Add test for narrowing to unions of string literals

* Rewrite isInStringLiteral to accomodate for unterminated strings

* Refactor signatureHelp to expose helper functions

* Add support for completion in string literals

* Remove unused check

* Use const instead of let

* Fix error

* Formatting changes

* Use shorthand properties

* Add failing test for #8738

* Sort baseline reference identifier by name

* Detects assignment to internal module export clause, fixes #8738

* add SharedArrayBuffer

fix

* Factor out assignment op check

* Add test for composite assignment

* Factor out the behaviour and handles x++ and ++x

* Handles ES3 default as identifier name

* Fix missing else statement

* isNameOfExportedDeclarationInNonES6Module

* Reorder options alphabetically

* Mark diagnostics, and skipDefaultLibCheck as internal

* Allow an import of "foo.js" to be matched by a file "foo.ts"

* Improve loadModuleFromFile code

* Respond to PR comments

* Respond to more PR comments

* Fix test

* Actually merge from master

* Revert to old tryLoad implementation

* Run fixupParentReferences when parsing isolated jsDocComment

* initial revision of unit test support for project system in tsserver

* Allow wildcard ("*") patterns in ambient module declarations

* Add non-widening forms of null and undefined

* Create separate control flows for property declarations with initializers

* Add regression test

* Allow trailing commas in function parameter and argument lists

* Add tests

* Remove unused variable

* Add null check and CR feedback

* Support shorthand ambient module declarations

* Revert "Merge pull request #7235 from weswigham/narrow-all-types"

This reverts commit ef0f6c8fe4f94a7e294cfe42d7025c9dca6535d5, reversing
changes made to 9f087cb62ade7a879e23c229df752fc8f87d679c.

* reuse the fixupParentReferences function

* Improve typing of && operator with --strictNullChecks

* Add test

* Respond to PR comments

* Respond to PR comments

* Add merging tests

* Use a function `stringify` to simplify calls to `JSON.stringify(xyz, undefined, 2)`

* Update tests

* Fix mistake

* Include indent in navigation bar protocol

Previously navbar01 test had indents when run in the browser but not when run from node. Now they run the same.

* Remove unnecessary restrictions in property access narrowing

* Fix fourslash test

* Add regression test

* Consider property declarations to be control flow containers

* Adding regression test

* Remove restriction on --target es5 and --module es6

* change type definition for Object.create

* Fix signature help

* Add "implicit any" warning for shorthand ambient modules

* Remove trailing whitespace

* Support using string values in enums for CompilerOptions in transpile methods

* Remove trailing whitespace in jakefile

* Make `jake runtests-browser` support test regexes with spaces

For example: `jake runtests-browser t="transpile .js files"` now works.

* Add another test

* factor out isJsxOrTsxExtension

* Move to a conformance test

* Revert "Revert "Merge pull request #7235 from weswigham/narrow-all-types""

This reverts commit fc3e040c5167868ed623612e8f33fb3beedf73b1.

* Use inclusive flag, as originally done, but include almost everything

* Add additional tests

* Respond to PR comments

* Fix typo

* add tests for tsserver project system

* Fix test

* Allow case comparison to undefined and null in strict null checking mode

* Remove incorrectly added tests

* check if moduleResolution when verifying that program can be reused

* more tests for module resolution change and exclude

* Fix linting issues

* Merge JSDoc of assignments from function expressions

* Allow nested assignments in type guards

* Add tests

* Improve order of parameter's merged jsdoc

* Force LF newlines for LKG builds/non debug builds
Fixes 6630

* Create intersection types in type guards for unrelated types

* Split commentsFunction test into expr/decl

And renumber.

* Remove TODO comments

* Accept new baselines

* Add tests

* Remove comments

* Fix test helper

* Recognize relative path using in outDir property (#9025)

* Recognize relative path using in outDir property

* Add projects tests

* Add project .json files

* Update baselines

* Add comments

* Add test case

The test passes in 1.8 and fails in master.

* Return trace when exception happens

* Remove Long-Done TODO

AFAIK, the harness sources have been concatenated into `run.js` for as long as I've known. This stops executing them twice (and in turn makes debugging tests much easier, since you no longer have to debug into eval'd code).

* Allow primitive type guards with typeof on right

Previously, only type guards of the form `typeof x === 'string'` were
allowed. Now you can write `'string' === typeof x`.

* Primitive type guards are now order independent

* Fix comments in tests

* Add handleing for classes

* Add more tests for target=es5 module=es6

* addExportToArgumentListKind

* Accept baseline

* Add more tests

* wip-fixing transforms

* Adds progress indicators to the runtests-parallel build task.

* Fixed typo

* Fix comment

* Add test for out-of-range error

* Use proper method of not resolving alias

* Fix module loading error

(commandLineOptions_stringToEnum would be undefined if optionDeclarations wasn't loaded yet)

* Port 8739

* Update tests

* Update baselines

* Contextually type return statement in async function

* Remove stale files

* Undo change

* Improve perf

* Improve tests

* Fix sourcemaps for debugging tests

* Allow --sourceRoot with --inlineSources option
Fixes #8445

* this in parameter initializers resolves to class

Accept baselines now that the test passes.

* Add tests for more kinds of import/export

* Fix7334 Disallow async in functionExpression and ArrowFunction (#9062)

* Error when using async modifier in function-expression and arrow-function when target es5

* Add tests and baselines

* Resolve function-this in parameter initialisers when explicitly provided

* Allow null/undefined guard with null/undefined on left

Also add a test with baselines.

* Code review comments

* Update more diagnostic messages ES6->2015

Fix #8996 CC @mhegazy.

* Fixes an issue with runtests-parallel when global mocha is not installed.

* Update LKG

* Add tests

* fix baselines

* Recommend runtests-parallel in CONTRIBUTING

* Only inlineSourceMap when debugging through jake-browser (#9080)

* Only inlineSourceMap when debugging through jake-browser

* Address PR: fix typo in opt's property

* Manually port tests from PR 8470

* minor fix: add missing return clause

* Support using string values in enums for CompilerOptions in transpile methods

* Support using string values in enums for CompilerOptions in transpile methods

# Conflicts:
#	tests/cases/unittests/transpile.ts

* Fix test helper

* Add test for out-of-range error

* Fix module loading error

(commandLineOptions_stringToEnum would be undefined if optionDeclarations wasn't loaded yet)

* Use camel-case instead of snake-case (#9134)

* Manually add tests for PR 8988

* Allow wildcard ("*") patterns in ambient module declarations

* Respond to PR comments

* Add another test

* Improve perf

* Improve tests

* Update baseline from merging with master

* Address PR comment

* Update baseline

* Refactor how we retrieve binding-name cache in module transformer

* Temporary accept so we get a clean run-tests result
2016-06-14 11:36:57 -07:00

360 lines
11 KiB
TypeScript

var tty = require("tty")
, readline = require("readline")
, fs = require("fs")
, path = require("path")
, child_process = require("child_process")
, os = require("os")
, mocha = require("mocha")
, Base = mocha.reporters.Base
, color = Base.color
, cursor = Base.cursor
, ms = require("mocha/lib/ms");
var isatty = tty.isatty(1) && tty.isatty(2);
var tapRangePattern = /^(\d+)\.\.(\d+)(?:$|\r\n?|\n)/;
var tapTestPattern = /^(not\sok|ok)\s+(\d+)\s+(?:-\s+)?(.*)$/;
var tapCommentPattern = /^#(?: (tests|pass|fail) (\d+)$)?/;
exports.runTestsInParallel = runTestsInParallel;
exports.ProgressBars = ProgressBars;
function runTestsInParallel(taskConfigsFolder, run, options, cb) {
if (options === undefined) options = { };
return discoverTests(run, options, function (error) {
if (error) {
return cb(error);
}
return runTests(taskConfigsFolder, run, options, cb);
});
}
function discoverTests(run, options, cb) {
console.log("Discovering tests...");
var cmd = "mocha -R " + require.resolve("./mocha-none-reporter.js") + " " + run;
var p = spawnProcess(cmd);
p.on("exit", function (status) {
if (status) {
cb(new Error("Process exited with code " + status));
}
else {
cb();
}
});
}
function runTests(taskConfigsFolder, run, options, cb) {
var configFiles = fs.readdirSync(taskConfigsFolder);
var numPartitions = configFiles.length;
if (numPartitions <= 0) {
cb();
return;
}
console.log("Running tests on " + numPartitions + " threads...");
var partitions = Array(numPartitions);
var progressBars = new ProgressBars();
progressBars.enable();
var counter = numPartitions;
configFiles.forEach(runTestsInPartition);
function runTestsInPartition(file, index) {
var partition = {
file: path.join(taskConfigsFolder, file),
tests: 0,
passed: 0,
failed: 0,
completed: 0,
current: undefined,
start: undefined,
end: undefined,
failures: []
};
partitions[index] = partition;
// Set up the progress bar.
updateProgress(0);
// Start the background process.
var cmd = "mocha -t " + (options.testTimeout || 20000) + " -R tap --no-colors " + run + " --config='" + partition.file + "'";
var p = spawnProcess(cmd);
var rl = readline.createInterface({
input: p.stdout,
terminal: false
});
rl.on("line", onmessage);
p.on("exit", onexit)
function onmessage(line) {
if (partition.start === undefined) {
partition.start = Date.now();
}
var rangeMatch = tapRangePattern.exec(line);
if (rangeMatch) {
partition.tests = parseInt(rangeMatch[2]);
return;
}
var testMatch = tapTestPattern.exec(line);
if (testMatch) {
var test = {
result: testMatch[1],
id: parseInt(testMatch[2]),
name: testMatch[3],
output: []
};
partition.current = test;
partition.completed++;
if (test.result === "ok") {
partition.passed++;
}
else {
partition.failed++;
partition.failures.push(test);
}
var progress = partition.completed / partition.tests;
if (progress < 1) {
updateProgress(progress);
}
return;
}
var commentMatch = tapCommentPattern.exec(line);
if (commentMatch) {
switch (commentMatch[1]) {
case "tests":
partition.current = undefined;
partition.tests = parseInt(commentMatch[2]);
break;
case "pass":
partition.passed = parseInt(commentMatch[2]);
break;
case "fail":
partition.failed = parseInt(commentMatch[2]);
break;
}
return;
}
if (partition.current) {
partition.current.output.push(line);
}
}
function onexit() {
if (partition.end === undefined) {
partition.end = Date.now();
}
partition.duration = partition.end - partition.start;
var summaryColor = partition.failed ? "fail" : "green";
var summarySymbol = partition.failed ? Base.symbols.err : Base.symbols.ok;
var summaryTests = (partition.passed === partition.tests ? partition.passed : partition.passed + "/" + partition.tests) + " passing";
var summaryDuration = "(" + ms(partition.duration) + ")";
var savedUseColors = Base.useColors;
Base.useColors = !options.noColors;
var summary = color(summaryColor, summarySymbol + " " + summaryTests) + " " + color("light", summaryDuration);
Base.useColors = savedUseColors;
updateProgress(1, summary);
signal();
}
function updateProgress(percentComplete, title) {
var progressColor = "pending";
if (partition.failed) {
progressColor = "fail";
}
progressBars.update(
index,
percentComplete,
progressColor,
title
);
}
}
function signal() {
counter--;
if (counter <= 0) {
var failed = 0;
var reporter = new Base(),
stats = reporter.stats,
failures = reporter.failures;
var duration = 0;
for (var i = 0; i < numPartitions; i++) {
var partition = partitions[i];
stats.passes += partition.passed;
stats.failures += partition.failed;
stats.tests += partition.tests;
duration += partition.duration;
for (var j = 0; j < partition.failures.length; j++) {
var failure = partition.failures[j];
failures.push(makeMochaTest(failure));
}
}
stats.duration = duration;
progressBars.disable();
if (options.noColors) {
var savedUseColors = Base.useColors;
Base.useColors = false;
reporter.epilogue();
Base.useColors = savedUseColors;
}
else {
reporter.epilogue();
}
if (failed) {
return cb(new Error("Test failures reported: " + failed));
}
else {
return cb();
}
}
}
function makeMochaTest(test) {
return {
fullTitle: function() {
return test.name;
},
err: {
message: test.output[0],
stack: test.output.join(os.EOL)
}
};
}
}
function spawnProcess(cmd, options) {
var shell = process.platform === "win32" ? "cmd" : "/bin/sh";
var prefix = process.platform === "win32" ? "/c" : "-c";
return child_process.spawn(shell, [prefix, cmd], { windowsVerbatimArguments: true });
}
function ProgressBars(options) {
if (!options) options = {};
var open = options.open || '[';
var close = options.close || ']';
var complete = options.complete || '▬';
var incomplete = options.incomplete || Base.symbols.dot;
var maxWidth = Math.floor(Base.window.width * .30) - open.length - close.length - 2;
var width = minMax(options.width || maxWidth, 10, maxWidth);
this._options = {
open: open,
complete: complete,
incomplete: incomplete,
close: close,
width: width
};
this._progressBars = [];
this._lineCount = 0;
this._enabled = false;
}
ProgressBars.prototype = {
enable: function () {
if (!this._enabled) {
process.stdout.write(os.EOL);
this._enabled = true;
}
},
disable: function () {
if (this._enabled) {
process.stdout.write(os.EOL);
this._enabled = false;
}
},
update: function (index, percentComplete, color, title) {
percentComplete = minMax(percentComplete, 0, 1);
var progressBar = this._progressBars[index] || (this._progressBars[index] = { });
var width = this._options.width;
var n = Math.floor(width * percentComplete);
var i = width - n;
if (n === progressBar.lastN && title === progressBar.title && color === progressBar.progressColor) {
return;
}
progressBar.lastN = n;
progressBar.title = title;
progressBar.progressColor = color;
var progress = " ";
progress += this._color('progress', this._options.open);
progress += this._color(color, fill(this._options.complete, n));
progress += this._color('progress', fill(this._options.incomplete, i));
progress += this._color('progress', this._options.close);
if (title) {
progress += this._color('progress', ' ' + title);
}
if (progressBar.text !== progress) {
progressBar.text = progress;
this._render(index);
}
},
_render: function (index) {
if (!this._enabled || !isatty) {
return;
}
cursor.hide();
readline.moveCursor(process.stdout, -process.stdout.columns, -this._lineCount);
var lineCount = 0;
var numProgressBars = this._progressBars.length;
for (var i = 0; i < numProgressBars; i++) {
if (i === index) {
readline.clearLine(process.stdout, 1);
process.stdout.write(this._progressBars[i].text + os.EOL);
}
else {
readline.moveCursor(process.stdout, -process.stdout.columns, +1);
}
lineCount++;
}
this._lineCount = lineCount;
cursor.show();
},
_color: function (type, text) {
return type && !this._options.noColors ? color(type, text) : text;
}
};
function fill(ch, size) {
var s = "";
while (s.length < size) {
s += ch;
}
return s.length > size ? s.substr(0, size) : s;
}
function minMax(value, min, max) {
if (value < min) return min;
if (value > max) return max;
return value;
}