diff --git a/_infrastructure/tests/runner.js b/_infrastructure/tests/runner.js
index 33afa7ed4..190285474 100644
--- a/_infrastructure/tests/runner.js
+++ b/_infrastructure/tests/runner.js
@@ -1,4 +1,558 @@
-///
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+var ExecResult = (function () {
+ function ExecResult() {
+ this.stdout = "";
+ this.stderr = "";
+ }
+ return ExecResult;
+})();
+
+var WindowsScriptHostExec = (function () {
+ function WindowsScriptHostExec() {
+ }
+ WindowsScriptHostExec.prototype.exec = function (filename, cmdLineArgs, handleResult) {
+ var result = new ExecResult();
+ var shell = new ActiveXObject('WScript.Shell');
+ try {
+ var process = shell.Exec(filename + ' ' + cmdLineArgs.join(' '));
+ } catch (e) {
+ result.stderr = e.message;
+ result.exitCode = 1;
+ handleResult(result);
+ return;
+ }
+
+ while (process.Status != 0) {
+ }
+
+ result.exitCode = process.ExitCode;
+ if (!process.StdOut.AtEndOfStream)
+ result.stdout = process.StdOut.ReadAll();
+ if (!process.StdErr.AtEndOfStream)
+ result.stderr = process.StdErr.ReadAll();
+
+ handleResult(result);
+ };
+ return WindowsScriptHostExec;
+})();
+
+var NodeExec = (function () {
+ function NodeExec() {
+ }
+ NodeExec.prototype.exec = function (filename, cmdLineArgs, handleResult) {
+ var nodeExec = require('child_process').exec;
+
+ var result = new ExecResult();
+ result.exitCode = null;
+ var cmdLine = filename + ' ' + cmdLineArgs.join(' ');
+
+ var process = nodeExec(cmdLine, function (error, stdout, stderr) {
+ result.stdout = stdout;
+ result.stderr = stderr;
+ result.exitCode = error ? error.code : 0;
+ handleResult(result);
+ });
+ };
+ return NodeExec;
+})();
+
+var Exec = (function () {
+ var global = Function("return this;").call(null);
+ if (typeof global.ActiveXObject !== "undefined") {
+ return new WindowsScriptHostExec();
+ } else {
+ return new NodeExec();
+ }
+})();
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+var IOUtils;
+(function (IOUtils) {
+ // Creates the directory including its parent if not already present
+ function createDirectoryStructure(ioHost, dirName) {
+ if (ioHost.directoryExists(dirName)) {
+ return;
+ }
+
+ var parentDirectory = ioHost.dirName(dirName);
+ if (parentDirectory != "") {
+ createDirectoryStructure(ioHost, parentDirectory);
+ }
+ ioHost.createDirectory(dirName);
+ }
+
+ // Creates a file including its directory structure if not already present
+ function createFileAndFolderStructure(ioHost, fileName, useUTF8) {
+ var path = ioHost.resolvePath(fileName);
+ var dirName = ioHost.dirName(path);
+ createDirectoryStructure(ioHost, dirName);
+ return ioHost.createFile(path, useUTF8);
+ }
+ IOUtils.createFileAndFolderStructure = createFileAndFolderStructure;
+
+ function throwIOError(message, error) {
+ var errorMessage = message;
+ if (error && error.message) {
+ errorMessage += (" " + error.message);
+ }
+ throw new Error(errorMessage);
+ }
+ IOUtils.throwIOError = throwIOError;
+})(IOUtils || (IOUtils = {}));
+
+var IO = (function () {
+ // Create an IO object for use inside WindowsScriptHost hosts
+ // Depends on WSCript and FileSystemObject
+ function getWindowsScriptHostIO() {
+ var fso = new ActiveXObject("Scripting.FileSystemObject");
+ var streamObjectPool = [];
+
+ function getStreamObject() {
+ if (streamObjectPool.length > 0) {
+ return streamObjectPool.pop();
+ } else {
+ return new ActiveXObject("ADODB.Stream");
+ }
+ }
+
+ function releaseStreamObject(obj) {
+ streamObjectPool.push(obj);
+ }
+
+ var args = [];
+ for (var i = 0; i < WScript.Arguments.length; i++) {
+ args[i] = WScript.Arguments.Item(i);
+ }
+
+ return {
+ readFile: function (path) {
+ try {
+ var streamObj = getStreamObject();
+ streamObj.Open();
+ streamObj.Type = 2;
+ streamObj.Charset = 'x-ansi';
+ streamObj.LoadFromFile(path);
+ var bomChar = streamObj.ReadText(2);
+ streamObj.Position = 0;
+ if ((bomChar.charCodeAt(0) == 0xFE && bomChar.charCodeAt(1) == 0xFF) || (bomChar.charCodeAt(0) == 0xFF && bomChar.charCodeAt(1) == 0xFE)) {
+ streamObj.Charset = 'unicode';
+ } else if (bomChar.charCodeAt(0) == 0xEF && bomChar.charCodeAt(1) == 0xBB) {
+ streamObj.Charset = 'utf-8';
+ }
+
+ // Read the whole file
+ var str = streamObj.ReadText(-1);
+ streamObj.Close();
+ releaseStreamObject(streamObj);
+ return str;
+ } catch (err) {
+ IOUtils.throwIOError("Error reading file \"" + path + "\".", err);
+ }
+ },
+ writeFile: function (path, contents) {
+ var file = this.createFile(path);
+ file.Write(contents);
+ file.Close();
+ },
+ fileExists: function (path) {
+ return fso.FileExists(path);
+ },
+ resolvePath: function (path) {
+ return fso.GetAbsolutePathName(path);
+ },
+ dirName: function (path) {
+ return fso.GetParentFolderName(path);
+ },
+ findFile: function (rootPath, partialFilePath) {
+ var path = fso.GetAbsolutePathName(rootPath) + "/" + partialFilePath;
+
+ while (true) {
+ if (fso.FileExists(path)) {
+ try {
+ var content = this.readFile(path);
+ return { content: content, path: path };
+ } catch (err) {
+ //Tools.CompilerDiagnostics.debugPrint("Could not find " + path + ", trying parent");
+ }
+ } else {
+ rootPath = fso.GetParentFolderName(fso.GetAbsolutePathName(rootPath));
+
+ if (rootPath == "") {
+ return null;
+ } else {
+ path = fso.BuildPath(rootPath, partialFilePath);
+ }
+ }
+ }
+ },
+ deleteFile: function (path) {
+ try {
+ if (fso.FileExists(path)) {
+ fso.DeleteFile(path, true);
+ }
+ } catch (e) {
+ IOUtils.throwIOError("Couldn't delete file '" + path + "'.", e);
+ }
+ },
+ createFile: function (path, useUTF8) {
+ try {
+ var streamObj = getStreamObject();
+ streamObj.Charset = useUTF8 ? 'utf-8' : 'x-ansi';
+ streamObj.Open();
+ return {
+ Write: function (str) {
+ streamObj.WriteText(str, 0);
+ },
+ WriteLine: function (str) {
+ streamObj.WriteText(str, 1);
+ },
+ Close: function () {
+ try {
+ streamObj.SaveToFile(path, 2);
+ } catch (saveError) {
+ IOUtils.throwIOError("Couldn't write to file '" + path + "'.", saveError);
+ } finally {
+ if (streamObj.State != 0) {
+ streamObj.Close();
+ }
+ releaseStreamObject(streamObj);
+ }
+ }
+ };
+ } catch (creationError) {
+ IOUtils.throwIOError("Couldn't write to file '" + path + "'.", creationError);
+ }
+ },
+ directoryExists: function (path) {
+ return fso.FolderExists(path);
+ },
+ createDirectory: function (path) {
+ try {
+ if (!this.directoryExists(path)) {
+ fso.CreateFolder(path);
+ }
+ } catch (e) {
+ IOUtils.throwIOError("Couldn't create directory '" + path + "'.", e);
+ }
+ },
+ dir: function (path, spec, options) {
+ options = options || {};
+ function filesInFolder(folder, root) {
+ var paths = [];
+ var fc;
+
+ if (options.recursive) {
+ fc = new Enumerator(folder.subfolders);
+
+ for (; !fc.atEnd(); fc.moveNext()) {
+ paths = paths.concat(filesInFolder(fc.item(), root + "/" + fc.item().Name));
+ }
+ }
+
+ fc = new Enumerator(folder.files);
+
+ for (; !fc.atEnd(); fc.moveNext()) {
+ if (!spec || fc.item().Name.match(spec)) {
+ paths.push(root + "/" + fc.item().Name);
+ }
+ }
+
+ return paths;
+ }
+
+ var folder = fso.GetFolder(path);
+ var paths = [];
+
+ return filesInFolder(folder, path);
+ },
+ print: function (str) {
+ WScript.StdOut.Write(str);
+ },
+ printLine: function (str) {
+ WScript.Echo(str);
+ },
+ arguments: args,
+ stderr: WScript.StdErr,
+ stdout: WScript.StdOut,
+ watchFile: null,
+ run: function (source, filename) {
+ try {
+ eval(source);
+ } catch (e) {
+ IOUtils.throwIOError("Error while executing file '" + filename + "'.", e);
+ }
+ },
+ getExecutingFilePath: function () {
+ return WScript.ScriptFullName;
+ },
+ quit: function (exitCode) {
+ if (typeof exitCode === "undefined") { exitCode = 0; }
+ try {
+ WScript.Quit(exitCode);
+ } catch (e) {
+ }
+ }
+ };
+ }
+ ;
+
+ // Create an IO object for use inside Node.js hosts
+ // Depends on 'fs' and 'path' modules
+ function getNodeIO() {
+ var _fs = require('fs');
+ var _path = require('path');
+ var _module = require('module');
+
+ return {
+ readFile: function (file) {
+ try {
+ var buffer = _fs.readFileSync(file);
+ switch (buffer[0]) {
+ case 0xFE:
+ if (buffer[1] == 0xFF) {
+ // utf16-be. Reading the buffer as big endian is not supported, so convert it to
+ // Little Endian first
+ var i = 0;
+ while ((i + 1) < buffer.length) {
+ var temp = buffer[i];
+ buffer[i] = buffer[i + 1];
+ buffer[i + 1] = temp;
+ i += 2;
+ }
+ return buffer.toString("ucs2", 2);
+ }
+ break;
+ case 0xFF:
+ if (buffer[1] == 0xFE) {
+ // utf16-le
+ return buffer.toString("ucs2", 2);
+ }
+ break;
+ case 0xEF:
+ if (buffer[1] == 0xBB) {
+ // utf-8
+ return buffer.toString("utf8", 3);
+ }
+ }
+
+ // Default behaviour
+ return buffer.toString();
+ } catch (e) {
+ IOUtils.throwIOError("Error reading file \"" + file + "\".", e);
+ }
+ },
+ writeFile: _fs.writeFileSync,
+ deleteFile: function (path) {
+ try {
+ _fs.unlinkSync(path);
+ } catch (e) {
+ IOUtils.throwIOError("Couldn't delete file '" + path + "'.", e);
+ }
+ },
+ fileExists: function (path) {
+ return _fs.existsSync(path);
+ },
+ createFile: function (path, useUTF8) {
+ function mkdirRecursiveSync(path) {
+ var stats = _fs.statSync(path);
+ if (stats.isFile()) {
+ IOUtils.throwIOError("\"" + path + "\" exists but isn't a directory.", null);
+ } else if (stats.isDirectory()) {
+ return;
+ } else {
+ mkdirRecursiveSync(_path.dirname(path));
+ _fs.mkdirSync(path, 0775);
+ }
+ }
+
+ mkdirRecursiveSync(_path.dirname(path));
+
+ try {
+ var fd = _fs.openSync(path, 'w');
+ } catch (e) {
+ IOUtils.throwIOError("Couldn't write to file '" + path + "'.", e);
+ }
+ return {
+ Write: function (str) {
+ _fs.writeSync(fd, str);
+ },
+ WriteLine: function (str) {
+ _fs.writeSync(fd, str + '\r\n');
+ },
+ Close: function () {
+ _fs.closeSync(fd);
+ fd = null;
+ }
+ };
+ },
+ dir: function dir(path, spec, options) {
+ options = options || {};
+
+ function filesInFolder(folder, deep) {
+ var paths = [];
+
+ var files = _fs.readdirSync(folder);
+ for (var i = 0; i < files.length; i++) {
+ var stat = _fs.statSync(folder + "/" + files[i]);
+ if (options.recursive && stat.isDirectory()) {
+ if (deep < (options.deep || 100)) {
+ paths = paths.concat(filesInFolder(folder + "/" + files[i], 1));
+ }
+ } else if (stat.isFile() && (!spec || files[i].match(spec))) {
+ paths.push(folder + "/" + files[i]);
+ }
+ }
+
+ return paths;
+ }
+
+ return filesInFolder(path, 0);
+ },
+ createDirectory: function (path) {
+ try {
+ if (!this.directoryExists(path)) {
+ _fs.mkdirSync(path);
+ }
+ } catch (e) {
+ IOUtils.throwIOError("Couldn't create directory '" + path + "'.", e);
+ }
+ },
+ directoryExists: function (path) {
+ return _fs.existsSync(path) && _fs.lstatSync(path).isDirectory();
+ },
+ resolvePath: function (path) {
+ return _path.resolve(path);
+ },
+ dirName: function (path) {
+ return _path.dirname(path);
+ },
+ findFile: function (rootPath, partialFilePath) {
+ var path = rootPath + "/" + partialFilePath;
+
+ while (true) {
+ if (_fs.existsSync(path)) {
+ try {
+ var content = this.readFile(path);
+ return { content: content, path: path };
+ } catch (err) {
+ //Tools.CompilerDiagnostics.debugPrint(("Could not find " + path) + ", trying parent");
+ }
+ } else {
+ var parentPath = _path.resolve(rootPath, "..");
+
+ if (rootPath === parentPath) {
+ return null;
+ } else {
+ rootPath = parentPath;
+ path = _path.resolve(rootPath, partialFilePath);
+ }
+ }
+ }
+ },
+ print: function (str) {
+ process.stdout.write(str);
+ },
+ printLine: function (str) {
+ process.stdout.write(str + '\n');
+ },
+ arguments: process.argv.slice(2),
+ stderr: {
+ Write: function (str) {
+ process.stderr.write(str);
+ },
+ WriteLine: function (str) {
+ process.stderr.write(str + '\n');
+ },
+ Close: function () {
+ }
+ },
+ stdout: {
+ Write: function (str) {
+ process.stdout.write(str);
+ },
+ WriteLine: function (str) {
+ process.stdout.write(str + '\n');
+ },
+ Close: function () {
+ }
+ },
+ watchFile: function (filename, callback) {
+ var firstRun = true;
+ var processingChange = false;
+
+ var fileChanged = function (curr, prev) {
+ if (!firstRun) {
+ if (curr.mtime < prev.mtime) {
+ return;
+ }
+
+ _fs.unwatchFile(filename, fileChanged);
+ if (!processingChange) {
+ processingChange = true;
+ callback(filename);
+ setTimeout(function () {
+ processingChange = false;
+ }, 100);
+ }
+ }
+ firstRun = false;
+ _fs.watchFile(filename, { persistent: true, interval: 500 }, fileChanged);
+ };
+
+ fileChanged();
+ return {
+ filename: filename,
+ close: function () {
+ _fs.unwatchFile(filename, fileChanged);
+ }
+ };
+ },
+ run: function (source, filename) {
+ require.main.filename = filename;
+ require.main.paths = _module._nodeModulePaths(_path.dirname(_fs.realpathSync(filename)));
+ require.main._compile(source, filename);
+ },
+ getExecutingFilePath: function () {
+ return process.mainModule.filename;
+ },
+ quit: process.exit
+ };
+ }
+ ;
+
+ if (typeof ActiveXObject === "function")
+ return getWindowsScriptHostIO();
+else if (typeof require === "function")
+ return getNodeIO();
+else
+ return null;
+})();
+///
///
var DefinitelyTyped;
(function (DefinitelyTyped) {