diff --git a/Jakefile.js b/Jakefile.js index c88d6933d55..1f786fb230c 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -187,20 +187,20 @@ var harnessSources = harnessCoreSources.concat([ "protocol.d.ts", "session.ts", "client.ts", - "editorServices.ts", + "editorServices.ts" ].map(function (f) { return path.join(serverDirectory, f); })); var librarySourceMap = [ { target: "lib.core.d.ts", sources: ["header.d.ts", "core.d.ts"] }, - { target: "lib.dom.d.ts", sources: ["importcore.d.ts", "intl.d.ts", "dom.generated.d.ts"], }, - { target: "lib.webworker.d.ts", sources: ["importcore.d.ts", "intl.d.ts", "webworker.generated.d.ts"], }, - { target: "lib.scriptHost.d.ts", sources: ["importcore.d.ts", "scriptHost.d.ts"], }, - { target: "lib.d.ts", sources: ["header.d.ts", "core.d.ts", "intl.d.ts", "dom.generated.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"], }, - { target: "lib.core.es6.d.ts", sources: ["header.d.ts", "core.d.ts", "es6.d.ts"]}, + { target: "lib.dom.d.ts", sources: ["importcore.d.ts", "intl.d.ts", "dom.generated.d.ts"] }, + { target: "lib.webworker.d.ts", sources: ["importcore.d.ts", "intl.d.ts", "webworker.generated.d.ts"] }, + { target: "lib.scriptHost.d.ts", sources: ["importcore.d.ts", "scriptHost.d.ts"] }, + { target: "lib.d.ts", sources: ["header.d.ts", "core.d.ts", "intl.d.ts", "dom.generated.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"] }, + { target: "lib.core.es6.d.ts", sources: ["header.d.ts", "core.d.ts", "es6.d.ts"] }, { target: "lib.es6.d.ts", sources: ["header.d.ts", "es6.d.ts", "core.d.ts", "intl.d.ts", "dom.generated.d.ts", "dom.es6.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"] }, - { target: "lib.core.es7.d.ts", sources: ["header.d.ts", "core.d.ts", "es6.d.ts", "es7.d.ts"]}, + { target: "lib.core.es7.d.ts", sources: ["header.d.ts", "core.d.ts", "es6.d.ts", "es7.d.ts"] }, { target: "lib.es7.d.ts", sources: ["header.d.ts", "es6.d.ts", "es7.d.ts", "core.d.ts", "intl.d.ts", "dom.generated.d.ts", "dom.es6.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"] } ]; @@ -242,7 +242,7 @@ function concatenateFiles(destinationFile, sourceFiles) { } var useDebugMode = true; -var host = (process.env.host || process.env.TYPESCRIPT_HOST || "node"); +var host = process.env.host || process.env.TYPESCRIPT_HOST || "node"; var compilerFilename = "tsc.js"; var LKGCompiler = path.join(LKGDirectory, compilerFilename); var builtLocalCompiler = path.join(builtLocalDirectory, compilerFilename); @@ -291,7 +291,7 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts options += " --out " + outFile; } else { - options += " --module commonjs" + options += " --module commonjs"; } if(opts.noResolve) { @@ -306,7 +306,7 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts } if (opts.stripInternal) { - options += " --stripInternal" + options += " --stripInternal"; } if (useBuiltCompiler && !/^(no?|f(alse)?|0|-)$/i.test(process.env.USE_TRANSFORMS)) { @@ -448,9 +448,9 @@ file(scriptsTsdJson); task("tsd-scripts", [scriptsTsdJson], function () { var cmd = "tsd --config " + scriptsTsdJson + " install"; - console.log(cmd) + console.log(cmd); exec(cmd); -}, { async: true }) +}, { async: true }); var importDefinitelyTypedTestsDirectory = path.join(scriptsDirectory, "importDefinitelyTypedTests"); var importDefinitelyTypedTestsJs = path.join(importDefinitelyTypedTestsDirectory, "importDefinitelyTypedTests.js"); @@ -617,7 +617,7 @@ directory(builtLocalDirectory); var run = path.join(builtLocalDirectory, "run.js"); compileFile(run, harnessSources, [builtLocalDirectory, tscFile].concat(libraryTargets).concat(harnessSources), [], /*useBuiltCompiler:*/ true); -var internalTests = "internal/" +var internalTests = "internal/"; var localBaseline = "tests/baselines/local/"; var refBaseline = "tests/baselines/reference/"; @@ -845,7 +845,7 @@ function runConsoleTests(defaultReporter, defaultSubsets) { testTimeout = 100000; } - colors = process.env.colors || process.env.color + colors = process.env.colors || process.env.color; colors = colors ? ' --no-colors ' : ' --colors '; reporter = process.env.reporter || process.env.r || defaultReporter; @@ -853,7 +853,7 @@ function runConsoleTests(defaultReporter, defaultSubsets) { // default timeout is 2sec which really should be enough, but maybe we just need a small amount longer var subsetRegexes; if(defaultSubsets.length === 0) { - subsetRegexes = [tests] + subsetRegexes = [tests]; } else { var subsets = tests ? tests.split("|") : defaultSubsets; @@ -903,8 +903,8 @@ task("generate-code-coverage", ["tests", builtLocalDirectory], function () { }, { async: true }); // Browser tests -var nodeServerOutFile = 'tests/webTestServer.js' -var nodeServerInFile = 'tests/webTestServer.ts' +var nodeServerOutFile = 'tests/webTestServer.js'; +var nodeServerInFile = 'tests/webTestServer.ts'; compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, { noOutFile: true }); desc("Runs browserify on run.js to produce a file suitable for running tests in the browser"); @@ -916,7 +916,7 @@ task("browserify", ["tests", builtLocalDirectory, nodeServerOutFile], function() desc("Runs the tests using the built run.js file like 'jake runtests'. Syntax is jake runtests-browser. Additional optional parameters tests=[regex], port=, browser=[chrome|IE]"); task("runtests-browser", ["tests", "browserify", builtLocalDirectory, servicesFileInBrowserTest], function() { cleanTestDirs(); - host = "node" + host = "node"; port = process.env.port || process.env.p || '8888'; browser = process.env.browser || process.env.b || "IE"; tests = process.env.test || process.env.tests || process.env.t; @@ -930,13 +930,13 @@ task("runtests-browser", ["tests", "browserify", builtLocalDirectory, servicesFi } tests = tests ? tests : ''; - var cmd = host + " tests/webTestServer.js " + port + " " + browser + " " + tests + var cmd = host + " tests/webTestServer.js " + port + " " + browser + " " + tests; console.log(cmd); exec(cmd); }, {async: true}); function getDiffTool() { - var program = process.env['DIFF'] + var program = process.env['DIFF']; if (!program) { fail("Add the 'DIFF' environment variable to the path of the program you want to use."); } @@ -965,11 +965,11 @@ task("tests-debug", ["setDebugMode", "tests"]); // Makes the test results the new baseline desc("Makes the most recent test results the new baseline, overwriting the old baseline"); task("baseline-accept", function(hardOrSoft) { - if (!hardOrSoft || hardOrSoft == "hard") { + if (!hardOrSoft || hardOrSoft === "hard") { jake.rmRf(refBaseline); fs.renameSync(localBaseline, refBaseline); } - else if (hardOrSoft == "soft") { + else if (hardOrSoft === "soft") { var files = jake.readdirR(localBaseline); for (var i in files) { jake.cpR(files[i], refBaseline); @@ -1048,7 +1048,7 @@ task("update-sublime", ["local", serverFile], function() { }); var tslintRuleDir = "scripts/tslint"; -var tslintRules = ([ +var tslintRules = [ "nextLineRule", "noNullRule", "preferConstRule", @@ -1056,7 +1056,7 @@ var tslintRules = ([ "typeOperatorSpacingRule", "noInOperatorRule", "noIncrementDecrementRule" -]); +]; var tslintRulesFiles = tslintRules.map(function(p) { return path.join(tslintRuleDir, p + ".ts"); }); @@ -1081,7 +1081,7 @@ function getLinterOptions() { function lintFileContents(options, path, contents) { var ll = new Linter(path, contents, options); - console.log("Linting '" + path + "'.") + console.log("Linting '" + path + "'."); return ll.lint(); } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 27dc06135fc..80848d6bbed 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -424,7 +424,7 @@ namespace Utils { filtered.push(line); } - (error).stack = filtered.join(ts.sys.newLine); + (error).stack = filtered.join(Harness.IO.newLine()); } return error; @@ -751,7 +751,16 @@ namespace Harness { return dirPath; } export let directoryName: typeof IO.directoryName = Utils.memoize(directoryNameImpl); - export const resolvePath = (path: string) => directoryName(path); + + export function resolvePath(path: string) { + const response = Http.getFileFromServerSync(serverRoot + path + "?resolve=true"); + if (response.status === 200) { + return response.responseText; + } + else { + return null; + } + } export function fileExists(path: string): boolean { const response = Http.getFileFromServerSync(serverRoot + path); diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index f5df92bedbf..12a581f6520 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -463,32 +463,39 @@ class ProjectRunner extends RunnerBase { } }); - it("Baseline of emitted result (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => { if (testCase.baselineCheck) { + var lastError: any = undefined; ts.forEach(compilerResult.outputFiles, outputFile => { - - Harness.Baseline.runBaseline("Baseline of emitted result (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + outputFile.fileName, () => { - try { - return Harness.IO.readFile(getProjectOutputFolder(outputFile.fileName, compilerResult.moduleKind)); - } - catch (e) { - return undefined; - } - }); + try { + Harness.Baseline.runBaseline("Baseline of emitted result (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + outputFile.fileName, () => { + try { + return Harness.IO.readFile(getProjectOutputFolder(outputFile.fileName, compilerResult.moduleKind)); + } + catch (e) { + return undefined; + } + }); + } + catch (e) { + lastError = e; + } }); + + if (lastError) { + throw lastError; + } } }); - - it("SourceMapRecord for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => { - if (compilerResult.sourceMapData) { - Harness.Baseline.runBaseline("SourceMapRecord for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".sourcemap.txt", () => { - return Harness.SourceMapRecorder.getSourceMapRecord(compilerResult.sourceMapData, compilerResult.program, - ts.filter(compilerResult.outputFiles, outputFile => Harness.Compiler.isJS(outputFile.emittedFileName))); - }); - } - }); + // it("SourceMapRecord for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => { + // if (compilerResult.sourceMapData) { + // Harness.Baseline.runBaseline("SourceMapRecord for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".sourcemap.txt", () => { + // return Harness.SourceMapRecorder.getSourceMapRecord(compilerResult.sourceMapData, compilerResult.program, + // ts.filter(compilerResult.outputFiles, outputFile => Harness.Compiler.isJS(outputFile.emittedFileName))); + // }); + // } + // }); // Verify that all the generated .d.ts files compile diff --git a/src/harness/runner.ts b/src/harness/runner.ts index 04af7b6f066..2182c401348 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -40,8 +40,14 @@ let testConfigFile = Harness.IO.fileExists(mytestconfig) ? Harness.IO.readFile(mytestconfig) : (Harness.IO.fileExists(testconfig) ? Harness.IO.readFile(testconfig) : ""); +type TestConfig = { + tests?: string[]; + stackTraceLimit?: number | "full"; + light?: boolean; +}; + if (testConfigFile !== "") { - const testConfig = JSON.parse(testConfigFile); + const testConfig = JSON.parse(testConfigFile); if (testConfig.light) { Harness.lightMode = true; } @@ -49,12 +55,12 @@ if (testConfigFile !== "") { if (testConfig.stackTraceLimit === "full") { (Error).stackTraceLimit = Infinity; } - else if ((testConfig.stackTraceLimit | 0) > 0) { + else if ((+testConfig.stackTraceLimit | 0) > 0) { (Error).stackTraceLimit = testConfig.stackTraceLimit; } - if (testConfig.test && testConfig.test.length > 0) { - for (const option of testConfig.test) { + if (testConfig.tests && testConfig.tests.length > 0) { + for (const option of testConfig.tests) { if (!option) { continue; } diff --git a/tests/webTestServer.ts b/tests/webTestServer.ts index dab552e2619..9eaddc3c638 100644 --- a/tests/webTestServer.ts +++ b/tests/webTestServer.ts @@ -48,6 +48,53 @@ function log(msg: string) { } } + +let directorySeparator = "/"; + +function getRootLength(path: string): number { + if (path.charAt(0) === directorySeparator) { + if (path.charAt(1) !== directorySeparator) return 1; + const p1 = path.indexOf("/", 2); + if (p1 < 0) return 2; + const p2 = path.indexOf("/", p1 + 1); + if (p2 < 0) return p1 + 1; + return p2 + 1; + } + if (path.charAt(1) === ":") { + if (path.charAt(2) === directorySeparator) return 3; + return 2; + } + // Per RFC 1738 'file' URI schema has the shape file:/// + // if is omitted then it is assumed that host value is 'localhost', + // however slash after the omitted is not removed. + // file:///folder1/file1 - this is a correct URI + // file://folder2/file2 - this is an incorrect URI + if (path.lastIndexOf("file:///", 0) === 0) { + return "file:///".length; + } + const idx = path.indexOf("://"); + if (idx !== -1) { + return idx + "://".length; + } + return 0; +} + +function getDirectoryPath(path: string): any { + path = switchToForwardSlashes(path); + return path.substr(0, Math.max(getRootLength(path), path.lastIndexOf(directorySeparator))); +} + +function ensureDirectoriesExist(path: string) { + path = switchToForwardSlashes(path); + if (path.length > getRootLength(path) && !fs.existsSync(path)) { + const parentDirectory = getDirectoryPath(path); + ensureDirectoriesExist(parentDirectory); + if (!fs.existsSync(path)) { + fs.mkdirSync(path); + } + } +} + // Copied from the compiler sources function dir(path: string, spec?: string, options?: any) { options = options || <{ recursive?: boolean; }>{}; @@ -94,28 +141,16 @@ function deleteFolderRecursive(path: string) { }; function writeFile(path: string, data: any, opts: { recursive: boolean }) { - try { - fs.writeFileSync(path, data); - } catch (e) { - // assume file was written to a directory that exists, if not, start recursively creating them as necessary - var parts = switchToForwardSlashes(path).split('/'); - for (var i = 0; i < parts.length; i++) { - var subDir = parts.slice(0, i).join('/'); - if (!fs.existsSync(subDir)) { - fs.mkdir(subDir); - } - } - fs.writeFileSync(path, data); - } + ensureDirectoriesExist(getDirectoryPath(path)); + fs.writeFileSync(path, data); } /// Request Handling /// function handleResolutionRequest(filePath: string, res: http.ServerResponse) { - var resolvedPath = path.resolve(filePath, ''); - resolvedPath = resolvedPath.substring(resolvedPath.indexOf('tests')); + var resolvedPath = path.resolve(filePath); resolvedPath = switchToForwardSlashes(resolvedPath); - send('success', res, resolvedPath); + send('success', res, resolvedPath, 'text/javascript'); return; } @@ -174,6 +209,7 @@ function getRequestOperation(req: http.ServerRequest, filename: string) { else return RequestType.GetDir; } else { + var queryData: any = url.parse(req.url, true).query; if (req.method === 'GET' && queryData.resolve !== undefined) return RequestType.ResolveFile // mocha uses ?grep= query string as equivalent to the --grep command line option used to filter tests @@ -223,7 +259,7 @@ function handleRequestOperation(req: http.ServerRequest, res: http.ServerRespons send('success', res, null); break; case RequestType.WriteDir: - fs.mkdirSync(reqPath); + ensureDirectoriesExist(reqPath); send('success', res, null); break; case RequestType.DeleteFile: