diff --git a/Gulpfile.js b/Gulpfile.js index 5f4f365915dda..7f65318d688f7 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -19,6 +19,8 @@ const cmdLineOptions = require("./scripts/build/options"); const copyright = "CopyrightNotice.txt"; const cleanTasks = []; +const testRunner = "./built/local/testRunner/runner.js"; + const buildScripts = () => buildProject("scripts"); task("scripts", buildScripts); task("scripts").description = "Builds files in the 'scripts' folder."; @@ -92,6 +94,10 @@ const localize = async () => { } }; +const buildAll = () => buildProject("src"); + +task("moduleBuild", parallel(generateLibs, series(buildScripts, localize, buildAll))); + const buildDebugTools = () => buildProject("src/debug"); const cleanDebugTools = () => cleanProject("src/debug"); cleanTasks.push(cleanDebugTools); @@ -119,6 +125,12 @@ const localPreBuild = parallel(generateLibs, series(buildScripts, generateDiagno const preBuild = cmdLineOptions.lkg ? lkgPreBuild : localPreBuild; const buildServices = (() => { + // TODO(jakebailey): fix this for modules + return cb => { + console.log("!!!TODO!!! buildServices"); + cb(); + }; + // build typescriptServices.out.js const buildTypescriptServicesOut = () => buildProject("src/typescriptServices/tsconfig.json", cmdLineOptions); @@ -252,6 +264,12 @@ task("watch-min").flags = { }; const buildLssl = (() => { + // TODO(jakebailey): fix this for modules + return cb => { + console.log("!!!TODO!!! buildLssl"); + cb(); + }; + // build tsserverlibrary.out.js const buildServerLibraryOut = () => buildProject("src/tsserverlibrary/tsconfig.json", cmdLineOptions); @@ -424,8 +442,8 @@ task("watch-local").flags = { const preTest = parallel(buildTsc, buildTests, buildServices, buildLssl); preTest.displayName = "preTest"; -const runTests = () => runConsoleTests("built/local/run.js", "mocha-fivemat-progress-reporter", /*runInParallel*/ false, /*watchMode*/ false); -task("runtests", series(preBuild, preTest, runTests)); +const runTests = () => runConsoleTests(testRunner, "mocha-fivemat-progress-reporter", /*runInParallel*/ false, /*watchMode*/ false); +task("runtests", series(/*preBuild, preTest,*/ task("moduleBuild"), runTests)); // TODO(jakebailey): fix this for modules task("runtests").description = "Runs the tests using the built run.js file."; task("runtests").flags = { "-t --tests=": "Pattern for tests to run.", @@ -443,8 +461,8 @@ task("runtests").flags = { " --shardId": "1-based ID of this shard (default: 1)", }; -const runTestsParallel = () => runConsoleTests("built/local/run.js", "min", /*runInParallel*/ cmdLineOptions.workers > 1, /*watchMode*/ false); -task("runtests-parallel", series(preBuild, preTest, runTestsParallel)); +const runTestsParallel = () => runConsoleTests(testRunner, "min", /*runInParallel*/ cmdLineOptions.workers > 1, /*watchMode*/ false); +task("runtests-parallel", series(/*preBuild, preTest,*/ task("moduleBuild"), runTestsParallel)); // TODO(jakebailey): fix this for modules task("runtests-parallel").description = "Runs all the tests in parallel using the built run.js file."; task("runtests-parallel").flags = { " --light": "Run tests in light mode (fewer verifications, but tests run faster).", @@ -592,10 +610,10 @@ task("publish-nightly").description = "Runs `npm publish --tag next` to create a // write some kind of trigger file that indicates build completion that we could listen for instead. const watchRuntests = () => watch(["built/local/*.js", "tests/cases/**/*.ts", "tests/cases/**/tsconfig.json"], { delay: 5000 }, async () => { if (cmdLineOptions.tests || cmdLineOptions.failed) { - await runConsoleTests("built/local/run.js", "mocha-fivemat-progress-reporter", /*runInParallel*/ false, /*watchMode*/ true); + await runConsoleTests(testRunner, "mocha-fivemat-progress-reporter", /*runInParallel*/ false, /*watchMode*/ true); } else { - await runConsoleTests("built/local/run.js", "min", /*runInParallel*/ true, /*watchMode*/ true); + await runConsoleTests(testRunner, "min", /*runInParallel*/ true, /*watchMode*/ true); } }); task("watch", series(preBuild, preTest, parallel(watchLib, watchDiagnostics, watchServices, watchLssl, watchTests, watchRuntests))); diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 0dbf501863a63..fc267260ebf65 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -1522,7 +1522,14 @@ export let sys: System = (() => { } }, getExecutingFilePath() { - return __filename; + // This function previously returned a path like `built/local/tsc.js`. + // Now, with a module output, this file is now `built/local/compiler/sys.js`. + // We want to return a file that looks like the old one, so that callers + // can locate other assets like the lib.d.ts files. + // + // TODO(jakebailey): replace this function with one that returns the path + // to the lib folder (or package path)?. + return _path.join(_path.dirname(__dirname), "fake.js"); }, getCurrentDirectory, getDirectories, diff --git a/src/server/_namespaces/ts.server.ts b/src/server/_namespaces/ts.server.ts index 66e9ce997b7f3..91d9a909ae7f8 100644 --- a/src/server/_namespaces/ts.server.ts +++ b/src/server/_namespaces/ts.server.ts @@ -4,6 +4,8 @@ export * from "../../jsTyping/_namespaces/ts.server"; export * from "../types"; export * from "../utilitiesPublic"; export * from "../utilities"; +import * as protocol from "./ts.server.protocol"; +export { protocol }; export * from "../scriptInfo"; export * from "../typingsCache"; export * from "../project"; @@ -12,5 +14,3 @@ export * from "../moduleSpecifierCache"; export * from "../packageJsonCache"; export * from "../session"; export * from "../scriptVersionCache"; -import * as protocol from "./ts.server.protocol"; -export { protocol }; diff --git a/src/testRunner/_namespaces/Harness.ts b/src/testRunner/_namespaces/Harness.ts index eeef44fbd754b..caf03e950ac7e 100644 --- a/src/testRunner/_namespaces/Harness.ts +++ b/src/testRunner/_namespaces/Harness.ts @@ -2,10 +2,12 @@ export * from "../../harness/_namespaces/Harness"; export * from "../../loggedIO/_namespaces/Harness"; + +import * as Parallel from "./Harness.Parallel"; +export { Parallel }; + export * from "../fourslashRunner"; export * from "../compilerRunner"; export * from "../externalCompileRunner"; export * from "../test262Runner"; export * from "../runner"; -import * as Parallel from "./Harness.Parallel"; -export { Parallel }; diff --git a/src/testRunner/_namespaces/tests.ts b/src/testRunner/_namespaces/tests.ts new file mode 100644 index 0000000000000..26a4f7378d2a3 --- /dev/null +++ b/src/testRunner/_namespaces/tests.ts @@ -0,0 +1,186 @@ +// Tests; see tsconfig.json list + +import "../unittests/asserts"; +import "../unittests/base64"; +import "../unittests/builder"; +import "../unittests/comments"; +import "../unittests/compilerCore"; +import "../unittests/convertToBase64"; +import "../unittests/customTransforms"; +import "../unittests/factory"; +import "../unittests/incrementalParser"; +import "../unittests/jsDocParsing"; +import "../unittests/jsonParserRecovery"; +import "../unittests/moduleResolution"; +import "../unittests/parsePseudoBigInt"; +import "../unittests/paths"; +import "../unittests/printer"; +import "../unittests/programApi"; +import "../unittests/publicApi"; +import "../unittests/reuseProgramStructure"; +import "../unittests/semver"; +import "../unittests/transform"; +import "../unittests/config/commandLineParsing"; +import "../unittests/config/configurationExtension"; +import "../unittests/config/convertCompilerOptionsFromJson"; +import "../unittests/config/convertTypeAcquisitionFromJson"; +import "../unittests/config/initializeTSConfig"; +import "../unittests/config/matchFiles"; +import "../unittests/config/projectReferences"; +import "../unittests/config/showConfig"; +import "../unittests/config/tsconfigParsing"; +import "../unittests/config/tsconfigParsingWatchOptions"; +import "../unittests/evaluation/arraySpread"; +import "../unittests/evaluation/asyncArrow"; +import "../unittests/evaluation/asyncGenerator"; +import "../unittests/evaluation/awaiter"; +import "../unittests/evaluation/destructuring"; +import "../unittests/evaluation/externalModules"; +import "../unittests/evaluation/forAwaitOf"; +import "../unittests/evaluation/forOf"; +import "../unittests/evaluation/optionalCall"; +import "../unittests/evaluation/objectRest"; +import "../unittests/evaluation/superInStaticInitializer"; +import "../unittests/evaluation/templateLiteral"; +import "../unittests/evaluation/updateExpressionInModule"; +import "../unittests/services/cancellableLanguageServiceOperations"; +import "../unittests/services/colorization"; +import "../unittests/services/convertToAsyncFunction"; +import "../unittests/services/documentRegistry"; +import "../unittests/services/extract/constants"; +import "../unittests/services/extract/functions"; +import "../unittests/services/extract/symbolWalker"; +import "../unittests/services/extract/ranges"; +import "../unittests/services/hostNewLineSupport"; +import "../unittests/services/languageService"; +import "../unittests/services/organizeImports"; +import "../unittests/services/patternMatcher"; +import "../unittests/services/preProcessFile"; +import "../unittests/services/textChanges"; +import "../unittests/services/transpile"; +import "../unittests/tsbuild/amdModulesWithOut"; +import "../unittests/tsbuild/clean"; +import "../unittests/tsbuild/configFileErrors"; +import "../unittests/tsbuild/configFileExtends"; +import "../unittests/tsbuild/containerOnlyReferenced"; +import "../unittests/tsbuild/declarationEmit"; +import "../unittests/tsbuild/demo"; +import "../unittests/tsbuild/emitDeclarationOnly"; +import "../unittests/tsbuild/emptyFiles"; +import "../unittests/tsbuild/exitCodeOnBogusFile"; +import "../unittests/tsbuild/graphOrdering"; +import "../unittests/tsbuild/inferredTypeFromTransitiveModule"; +import "../unittests/tsbuild/javascriptProjectEmit"; +import "../unittests/tsbuild/lateBoundSymbol"; +import "../unittests/tsbuild/moduleResolution"; +import "../unittests/tsbuild/moduleSpecifiers"; +import "../unittests/tsbuild/noEmitOnError"; +import "../unittests/tsbuild/outFile"; +import "../unittests/tsbuild/outputPaths"; +import "../unittests/tsbuild/publicApi"; +import "../unittests/tsbuild/referencesWithRootDirInParent"; +import "../unittests/tsbuild/resolveJsonModule"; +import "../unittests/tsbuild/sample"; +import "../unittests/tsbuild/transitiveReferences"; +import "../unittests/tsbuildWatch/configFileErrors"; +import "../unittests/tsbuildWatch/demo"; +import "../unittests/tsbuildWatch/moduleResolution"; +import "../unittests/tsbuildWatch/noEmit"; +import "../unittests/tsbuildWatch/noEmitOnError"; +import "../unittests/tsbuildWatch/programUpdates"; +import "../unittests/tsbuildWatch/projectsBuilding"; +import "../unittests/tsbuildWatch/publicApi"; +import "../unittests/tsbuildWatch/reexport"; +import "../unittests/tsbuildWatch/watchEnvironment"; +import "../unittests/tsc/cancellationToken"; +import "../unittests/tsc/composite"; +import "../unittests/tsc/declarationEmit"; +import "../unittests/tsc/forceConsistentCasingInFileNames"; +import "../unittests/tsc/incremental"; +import "../unittests/tsc/listFilesOnly"; +import "../unittests/tsc/projectReferences"; +import "../unittests/tsc/redirect"; +import "../unittests/tsc/runWithoutArgs"; +import "../unittests/tscWatch/consoleClearing"; +import "../unittests/tscWatch/emit"; +import "../unittests/tscWatch/nodeNextWatch"; +import "../unittests/tscWatch/emitAndErrorUpdates"; +import "../unittests/tscWatch/forceConsistentCasingInFileNames"; +import "../unittests/tscWatch/incremental"; +import "../unittests/tscWatch/moduleResolution"; +import "../unittests/tscWatch/programUpdates"; +import "../unittests/tscWatch/projectsWithReferences"; +import "../unittests/tscWatch/resolutionCache"; +import "../unittests/tscWatch/sourceOfProjectReferenceRedirect"; +import "../unittests/tscWatch/watchApi"; +import "../unittests/tscWatch/watchEnvironment"; +import "../unittests/tsserver/applyChangesToOpenFiles"; +import "../unittests/tsserver/autoImportProvider"; +import "../unittests/tsserver/auxiliaryProject"; +import "../unittests/tsserver/cachingFileSystemInformation"; +import "../unittests/tsserver/cancellationToken"; +import "../unittests/tsserver/compileOnSave"; +import "../unittests/tsserver/completions"; +import "../unittests/tsserver/completionsIncomplete"; +import "../unittests/tsserver/configFileSearch"; +import "../unittests/tsserver/configuredProjects"; +import "../unittests/tsserver/declarationFileMaps"; +import "../unittests/tsserver/documentRegistry"; +import "../unittests/tsserver/duplicatePackages"; +import "../unittests/tsserver/dynamicFiles"; +import "../unittests/tsserver/events/largeFileReferenced"; +import "../unittests/tsserver/events/projectLanguageServiceState"; +import "../unittests/tsserver/events/projectLoading"; +import "../unittests/tsserver/events/projectUpdatedInBackground"; +import "../unittests/tsserver/exportMapCache"; +import "../unittests/tsserver/externalProjects"; +import "../unittests/tsserver/forceConsistentCasingInFileNames"; +import "../unittests/tsserver/formatSettings"; +import "../unittests/tsserver/getApplicableRefactors"; +import "../unittests/tsserver/getEditsForFileRename"; +import "../unittests/tsserver/getExportReferences"; +import "../unittests/tsserver/getFileReferences"; +import "../unittests/tsserver/importHelpers"; +import "../unittests/tsserver/inlayHints"; +import "../unittests/tsserver/inferredProjects"; +import "../unittests/tsserver/jsdocTag"; +import "../unittests/tsserver/languageService"; +import "../unittests/tsserver/maxNodeModuleJsDepth"; +import "../unittests/tsserver/metadataInResponse"; +import "../unittests/tsserver/moduleResolution"; +import "../unittests/tsserver/moduleSpecifierCache"; +import "../unittests/tsserver/navTo"; +import "../unittests/tsserver/occurences"; +import "../unittests/tsserver/openFile"; +import "../unittests/tsserver/packageJsonInfo"; +import "../unittests/tsserver/partialSemanticServer"; +import "../unittests/tsserver/plugins"; +import "../unittests/tsserver/projectErrors"; +import "../unittests/tsserver/projectReferenceCompileOnSave"; +import "../unittests/tsserver/projectReferenceErrors"; +import "../unittests/tsserver/projectReferences"; +import "../unittests/tsserver/projectReferencesSourcemap"; +import "../unittests/tsserver/projects"; +import "../unittests/tsserver/projectsWithReferences"; +import "../unittests/tsserver/refactors"; +import "../unittests/tsserver/reload"; +import "../unittests/tsserver/reloadProjects"; +import "../unittests/tsserver/rename"; +import "../unittests/tsserver/resolutionCache"; +import "../unittests/tsserver/session"; +import "../unittests/tsserver/skipLibCheck"; +import "../unittests/tsserver/smartSelection"; +import "../unittests/tsserver/symlinkCache"; +import "../unittests/tsserver/symLinks"; +import "../unittests/tsserver/syntacticServer"; +import "../unittests/tsserver/syntaxOperations"; +import "../unittests/tsserver/textStorage"; +import "../unittests/tsserver/telemetry"; +import "../unittests/tsserver/typeAquisition"; +import "../unittests/tsserver/typeOnlyImportChains"; +import "../unittests/tsserver/typeReferenceDirectives"; +import "../unittests/tsserver/typingsInstaller"; +import "../unittests/tsserver/versionCache"; +import "../unittests/tsserver/watchEnvironment"; +import "../unittests/tsserver/webServer"; +import "../unittests/debugDeprecation"; diff --git a/src/testRunner/_namespaces/ts.projectSystem.ts b/src/testRunner/_namespaces/ts.projectSystem.ts index 48038443996c7..2723fee96d7bc 100644 --- a/src/testRunner/_namespaces/ts.projectSystem.ts +++ b/src/testRunner/_namespaces/ts.projectSystem.ts @@ -1,69 +1,3 @@ /* Generated file to emulate the ts.projectSystem namespace. */ export * from "../unittests/tsserver/helpers"; -export * from "../unittests/tsserver/applyChangesToOpenFiles"; -export * from "../unittests/tsserver/autoImportProvider"; -export * from "../unittests/tsserver/auxiliaryProject"; -export * from "../unittests/tsserver/cachingFileSystemInformation"; -export * from "../unittests/tsserver/cancellationToken"; -export * from "../unittests/tsserver/compileOnSave"; -export * from "../unittests/tsserver/completions"; -export * from "../unittests/tsserver/completionsIncomplete"; -export * from "../unittests/tsserver/configFileSearch"; -export * from "../unittests/tsserver/configuredProjects"; -export * from "../unittests/tsserver/declarationFileMaps"; -export * from "../unittests/tsserver/documentRegistry"; -export * from "../unittests/tsserver/duplicatePackages"; -export * from "../unittests/tsserver/dynamicFiles"; -export * from "../unittests/tsserver/events/largeFileReferenced"; -export * from "../unittests/tsserver/events/projectLanguageServiceState"; -export * from "../unittests/tsserver/events/projectLoading"; -export * from "../unittests/tsserver/events/projectUpdatedInBackground"; -export * from "../unittests/tsserver/exportMapCache"; -export * from "../unittests/tsserver/externalProjects"; -export * from "../unittests/tsserver/forceConsistentCasingInFileNames"; -export * from "../unittests/tsserver/formatSettings"; -export * from "../unittests/tsserver/getApplicableRefactors"; -export * from "../unittests/tsserver/getEditsForFileRename"; -export * from "../unittests/tsserver/getExportReferences"; -export * from "../unittests/tsserver/getFileReferences"; -export * from "../unittests/tsserver/importHelpers"; -export * from "../unittests/tsserver/inlayHints"; -export * from "../unittests/tsserver/inferredProjects"; -export * from "../unittests/tsserver/jsdocTag"; -export * from "../unittests/tsserver/languageService"; -export * from "../unittests/tsserver/maxNodeModuleJsDepth"; -export * from "../unittests/tsserver/metadataInResponse"; -export * from "../unittests/tsserver/moduleResolution"; -export * from "../unittests/tsserver/moduleSpecifierCache"; -export * from "../unittests/tsserver/navTo"; -export * from "../unittests/tsserver/occurences"; -export * from "../unittests/tsserver/openFile"; -export * from "../unittests/tsserver/packageJsonInfo"; -export * from "../unittests/tsserver/partialSemanticServer"; -export * from "../unittests/tsserver/plugins"; -export * from "../unittests/tsserver/projectErrors"; -export * from "../unittests/tsserver/projectReferenceCompileOnSave"; -export * from "../unittests/tsserver/projectReferenceErrors"; -export * from "../unittests/tsserver/projectReferences"; -export * from "../unittests/tsserver/projectReferencesSourcemap"; -export * from "../unittests/tsserver/projects"; -export * from "../unittests/tsserver/projectsWithReferences"; -export * from "../unittests/tsserver/refactors"; -export * from "../unittests/tsserver/reload"; -export * from "../unittests/tsserver/reloadProjects"; -export * from "../unittests/tsserver/rename"; -export * from "../unittests/tsserver/resolutionCache"; -export * from "../unittests/tsserver/skipLibCheck"; -export * from "../unittests/tsserver/smartSelection"; -export * from "../unittests/tsserver/symlinkCache"; -export * from "../unittests/tsserver/symLinks"; -export * from "../unittests/tsserver/syntacticServer"; -export * from "../unittests/tsserver/syntaxOperations"; -export * from "../unittests/tsserver/telemetry"; -export * from "../unittests/tsserver/typeAquisition"; -export * from "../unittests/tsserver/typeOnlyImportChains"; -export * from "../unittests/tsserver/typeReferenceDirectives"; -export * from "../unittests/tsserver/typingsInstaller"; -export * from "../unittests/tsserver/watchEnvironment"; -export * from "../unittests/tsserver/webServer"; diff --git a/src/testRunner/_namespaces/ts.server.ts b/src/testRunner/_namespaces/ts.server.ts index 55f4afed9df57..225d9d4e6aa24 100644 --- a/src/testRunner/_namespaces/ts.server.ts +++ b/src/testRunner/_namespaces/ts.server.ts @@ -6,4 +6,3 @@ export * from "../../webServer/_namespaces/ts.server"; export * from "../../typingsInstallerCore/_namespaces/ts.server"; export * from "../../harness/_namespaces/ts.server"; export * from "../../loggedIO/_namespaces/ts.server"; -export * from "../unittests/tsserver/session"; diff --git a/src/testRunner/_namespaces/ts.textStorage.ts b/src/testRunner/_namespaces/ts.textStorage.ts index 1243be98aed05..5e49478c4dd12 100644 --- a/src/testRunner/_namespaces/ts.textStorage.ts +++ b/src/testRunner/_namespaces/ts.textStorage.ts @@ -1,3 +1,3 @@ /* Generated file to emulate the ts.textStorage namespace. */ -export * from "../unittests/tsserver/textStorage"; +export {}; diff --git a/src/testRunner/_namespaces/ts.ts b/src/testRunner/_namespaces/ts.ts index bc8b00ea696e6..060d53dcda145 100644 --- a/src/testRunner/_namespaces/ts.ts +++ b/src/testRunner/_namespaces/ts.ts @@ -10,86 +10,15 @@ export * from "../../typingsInstallerCore/_namespaces/ts"; export * from "../../deprecatedCompat/_namespaces/ts"; export * from "../../harness/_namespaces/ts"; export * from "../../loggedIO/_namespaces/ts"; -export * from "../unittests/services/extract/helpers"; -export * from "../unittests/tsbuild/helpers"; -export * from "../unittests/tsc/helpers"; -export * from "../unittests/asserts"; -export * from "../unittests/base64"; -export * from "../unittests/builder"; -export * from "../unittests/comments"; -export * from "../unittests/compilerCore"; -export * from "../unittests/convertToBase64"; -export * from "../unittests/customTransforms"; -export * from "../unittests/factory"; -export * from "../unittests/incrementalParser"; -export * from "../unittests/jsDocParsing"; -export * from "../unittests/jsonParserRecovery"; -export * from "../unittests/moduleResolution"; -export * from "../unittests/parsePseudoBigInt"; -export * from "../unittests/printer"; -export * from "../unittests/programApi"; -export * from "../unittests/reuseProgramStructure"; -export * from "../unittests/semver"; -export * from "../unittests/transform"; -export * from "../unittests/config/commandLineParsing"; -export * from "../unittests/config/configurationExtension"; -export * from "../unittests/config/convertCompilerOptionsFromJson"; -export * from "../unittests/config/convertTypeAcquisitionFromJson"; -export * from "../unittests/config/initializeTSConfig"; -export * from "../unittests/config/matchFiles"; -export * from "../unittests/config/projectReferences"; -export * from "../unittests/config/showConfig"; -export * from "../unittests/config/tsconfigParsing"; -export * from "../unittests/config/tsconfigParsingWatchOptions"; -export * from "../unittests/services/cancellableLanguageServiceOperations"; -export * from "../unittests/services/convertToAsyncFunction"; -export * from "../unittests/services/extract/constants"; -export * from "../unittests/services/extract/functions"; -export * from "../unittests/services/extract/symbolWalker"; -export * from "../unittests/services/extract/ranges"; -export * from "../unittests/services/hostNewLineSupport"; -export * from "../unittests/services/languageService"; -export * from "../unittests/services/organizeImports"; -export * from "../unittests/services/textChanges"; -export * from "../unittests/services/transpile"; -export * from "../unittests/tsbuild/amdModulesWithOut"; -export * from "../unittests/tsbuild/clean"; -export * from "../unittests/tsbuild/configFileErrors"; -export * from "../unittests/tsbuild/configFileExtends"; -export * from "../unittests/tsbuild/containerOnlyReferenced"; -export * from "../unittests/tsbuild/declarationEmit"; -export * from "../unittests/tsbuild/demo"; -export * from "../unittests/tsbuild/emitDeclarationOnly"; -export * from "../unittests/tsbuild/emptyFiles"; -export * from "../unittests/tsbuild/exitCodeOnBogusFile"; -export * from "../unittests/tsbuild/graphOrdering"; -export * from "../unittests/tsbuild/inferredTypeFromTransitiveModule"; -export * from "../unittests/tsbuild/javascriptProjectEmit"; -export * from "../unittests/tsbuild/lateBoundSymbol"; -export * from "../unittests/tsbuild/moduleSpecifiers"; -export * from "../unittests/tsbuild/noEmitOnError"; -export * from "../unittests/tsbuild/outFile"; -export * from "../unittests/tsbuild/outputPaths"; -export * from "../unittests/tsbuild/publicApi"; -export * from "../unittests/tsbuild/referencesWithRootDirInParent"; -export * from "../unittests/tsbuild/resolveJsonModule"; -export * from "../unittests/tsbuild/sample"; -export * from "../unittests/tsbuild/transitiveReferences"; -export * from "../unittests/tsc/composite"; -export * from "../unittests/tsc/declarationEmit"; -export * from "../unittests/tsc/forceConsistentCasingInFileNames"; -export * from "../unittests/tsc/incremental"; -export * from "../unittests/tsc/listFilesOnly"; -export * from "../unittests/tsc/projectReferences"; -export * from "../unittests/tsc/redirect"; -export * from "../unittests/tsc/runWithoutArgs"; -export * from "../unittests/tsserver/versionCache"; -export * from "../unittests/debugDeprecation"; import * as tscWatch from "./ts.tscWatch"; export { tscWatch }; -import * as projectSystem from "./ts.projectSystem"; -export { projectSystem }; import * as server from "./ts.server"; export { server }; +import * as projectSystem from "./ts.projectSystem"; +export { projectSystem }; import * as textStorage from "./ts.textStorage"; export { textStorage }; +export * from "../unittests/helpers"; +export * from "../unittests/services/extract/helpers"; +export * from "../unittests/tsbuild/helpers"; +export * from "../unittests/tsc/helpers"; diff --git a/src/testRunner/_namespaces/ts.tscWatch.ts b/src/testRunner/_namespaces/ts.tscWatch.ts index 3220ae1aa9239..aaa9390cb9e73 100644 --- a/src/testRunner/_namespaces/ts.tscWatch.ts +++ b/src/testRunner/_namespaces/ts.tscWatch.ts @@ -1,28 +1,3 @@ /* Generated file to emulate the ts.tscWatch namespace. */ export * from "../unittests/tscWatch/helpers"; -export * from "../unittests/tsbuild/moduleResolution"; -export * from "../unittests/tsbuildWatch/configFileErrors"; -export * from "../unittests/tsbuildWatch/demo"; -export * from "../unittests/tsbuildWatch/moduleResolution"; -export * from "../unittests/tsbuildWatch/noEmit"; -export * from "../unittests/tsbuildWatch/noEmitOnError"; -export * from "../unittests/tsbuildWatch/programUpdates"; -export * from "../unittests/tsbuildWatch/projectsBuilding"; -export * from "../unittests/tsbuildWatch/publicApi"; -export * from "../unittests/tsbuildWatch/reexport"; -export * from "../unittests/tsbuildWatch/watchEnvironment"; -export * from "../unittests/tsc/cancellationToken"; -export * from "../unittests/tscWatch/consoleClearing"; -export * from "../unittests/tscWatch/emit"; -export * from "../unittests/tscWatch/nodeNextWatch"; -export * from "../unittests/tscWatch/emitAndErrorUpdates"; -export * from "../unittests/tscWatch/forceConsistentCasingInFileNames"; -export * from "../unittests/tscWatch/incremental"; -export * from "../unittests/tscWatch/moduleResolution"; -export * from "../unittests/tscWatch/programUpdates"; -export * from "../unittests/tscWatch/projectsWithReferences"; -export * from "../unittests/tscWatch/resolutionCache"; -export * from "../unittests/tscWatch/sourceOfProjectReferenceRedirect"; -export * from "../unittests/tscWatch/watchApi"; -export * from "../unittests/tscWatch/watchEnvironment"; diff --git a/src/testRunner/parallel/host.ts b/src/testRunner/parallel/host.ts index 0b64fba829fad..96e5d93247228 100644 --- a/src/testRunner/parallel/host.ts +++ b/src/testRunner/parallel/host.ts @@ -263,7 +263,7 @@ export function start() { const configPath = ts.combinePaths(taskConfigsFolder, `task-config${i}.json`); IO.writeFile(configPath, JSON.stringify(config)); const worker: Worker = { - process: fork(__filename, [`--config="${configPath}"`], { stdio: ["pipe", "pipe", "pipe", "ipc"] }), + process: fork(process.argv[1], [`--config="${configPath}"`], { stdio: ["pipe", "pipe", "pipe", "ipc"] }), accumulatedOutput: "", currentTasks: undefined, timer: undefined diff --git a/src/testRunner/runner.ts b/src/testRunner/runner.ts index ff59c4e75250b..afce9655270a0 100644 --- a/src/testRunner/runner.ts +++ b/src/testRunner/runner.ts @@ -291,3 +291,6 @@ function startTestEnvironment() { } startTestEnvironment(); + +// This brings in all of the unittests. +import "./_namespaces/tests"; diff --git a/src/testRunner/tsconfig.json b/src/testRunner/tsconfig.json index 2ad4ff32e4404..1aa9033e1d6cd 100644 --- a/src/testRunner/tsconfig.json +++ b/src/testRunner/tsconfig.json @@ -50,6 +50,7 @@ "runner.ts", + "unittests/helpers.ts", "unittests/services/extract/helpers.ts", "unittests/tsbuild/helpers.ts", "unittests/tsc/helpers.ts", @@ -260,6 +261,7 @@ "_namespaces/ts.tscWatch.ts", "_namespaces/ts.projectSystem.ts", "_namespaces/ts.server.ts", - "_namespaces/ts.textStorage.ts" + "_namespaces/ts.textStorage.ts", + "_namespaces/tests.ts" ] } diff --git a/src/testRunner/unittests/helpers.ts b/src/testRunner/unittests/helpers.ts new file mode 100644 index 0000000000000..7706b16ab1a57 --- /dev/null +++ b/src/testRunner/unittests/helpers.ts @@ -0,0 +1,241 @@ +import * as ts from "../_namespaces/ts"; + +const enum ChangedPart { + references = 1 << 0, + importsAndExports = 1 << 1, + program = 1 << 2 +} + +export const newLine = "\r\n"; + +export interface SourceFileWithText extends ts.SourceFile { + sourceText?: SourceText; +} + +export interface NamedSourceText { + name: string; + text: SourceText; +} + +export interface ProgramWithSourceTexts extends ts.Program { + sourceTexts?: readonly NamedSourceText[]; + host: TestCompilerHost; +} + +export interface TestCompilerHost extends ts.CompilerHost { + getTrace(): string[]; +} + +export class SourceText implements ts.IScriptSnapshot { + private fullText: string | undefined; + + constructor(private references: string, + private importsAndExports: string, + private program: string, + private changedPart: ChangedPart = 0, + private version = 0) { + } + + static New(references: string, importsAndExports: string, program: string): SourceText { + ts.Debug.assert(references !== undefined); + ts.Debug.assert(importsAndExports !== undefined); + ts.Debug.assert(program !== undefined); + return new SourceText(references + newLine, importsAndExports + newLine, program || ""); + } + + public getVersion(): number { + return this.version; + } + + public updateReferences(newReferences: string): SourceText { + ts.Debug.assert(newReferences !== undefined); + return new SourceText(newReferences + newLine, this.importsAndExports, this.program, this.changedPart | ChangedPart.references, this.version + 1); + } + public updateImportsAndExports(newImportsAndExports: string): SourceText { + ts.Debug.assert(newImportsAndExports !== undefined); + return new SourceText(this.references, newImportsAndExports + newLine, this.program, this.changedPart | ChangedPart.importsAndExports, this.version + 1); + } + public updateProgram(newProgram: string): SourceText { + ts.Debug.assert(newProgram !== undefined); + return new SourceText(this.references, this.importsAndExports, newProgram, this.changedPart | ChangedPart.program, this.version + 1); + } + + public getFullText() { + return this.fullText || (this.fullText = this.references + this.importsAndExports + this.program); + } + + public getText(start: number, end: number): string { + return this.getFullText().substring(start, end); + } + + getLength(): number { + return this.getFullText().length; + } + + getChangeRange(oldSnapshot: ts.IScriptSnapshot): ts.TextChangeRange { + const oldText = oldSnapshot as SourceText; + let oldSpan: ts.TextSpan; + let newLength: number; + switch (oldText.changedPart ^ this.changedPart) { + case ChangedPart.references: + oldSpan = ts.createTextSpan(0, oldText.references.length); + newLength = this.references.length; + break; + case ChangedPart.importsAndExports: + oldSpan = ts.createTextSpan(oldText.references.length, oldText.importsAndExports.length); + newLength = this.importsAndExports.length; + break; + case ChangedPart.program: + oldSpan = ts.createTextSpan(oldText.references.length + oldText.importsAndExports.length, oldText.program.length); + newLength = this.program.length; + break; + default: + return ts.Debug.fail("Unexpected change"); + } + + return ts.createTextChangeRange(oldSpan, newLength); + } +} + +function createSourceFileWithText(fileName: string, sourceText: SourceText, target: ts.ScriptTarget) { + const file = ts.createSourceFile(fileName, sourceText.getFullText(), target) as SourceFileWithText; + file.sourceText = sourceText; + file.version = "" + sourceText.getVersion(); + return file; +} + +export function createTestCompilerHost(texts: readonly NamedSourceText[], target: ts.ScriptTarget, oldProgram?: ProgramWithSourceTexts, useGetSourceFileByPath?: boolean) { + const files = ts.arrayToMap(texts, t => t.name, t => { + if (oldProgram) { + let oldFile = oldProgram.getSourceFile(t.name) as SourceFileWithText; + if (oldFile && oldFile.redirectInfo) { + oldFile = oldFile.redirectInfo.unredirected; + } + if (oldFile && oldFile.sourceText!.getVersion() === t.text.getVersion()) { + return oldFile; + } + } + return createSourceFileWithText(t.name, t.text, target); + }); + const useCaseSensitiveFileNames = ts.sys && ts.sys.useCaseSensitiveFileNames; + const getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames); + const trace: string[] = []; + const result: TestCompilerHost = { + trace: s => trace.push(s), + getTrace: () => trace, + getSourceFile: fileName => files.get(fileName), + getDefaultLibFileName: () => "lib.d.ts", + writeFile: ts.notImplemented, + getCurrentDirectory: () => "", + getDirectories: () => [], + getCanonicalFileName, + useCaseSensitiveFileNames: () => useCaseSensitiveFileNames, + getNewLine: () => ts.sys ? ts.sys.newLine : newLine, + fileExists: fileName => files.has(fileName), + readFile: fileName => { + const file = files.get(fileName); + return file && file.text; + }, + }; + if (useGetSourceFileByPath) { + const filesByPath = ts.mapEntries(files, (fileName, file) => [ts.toPath(fileName, "", getCanonicalFileName), file]); + result.getSourceFileByPath = (_fileName, path) => filesByPath.get(path); + } + return result; +} + +export function newProgram(texts: NamedSourceText[], rootNames: string[], options: ts.CompilerOptions, useGetSourceFileByPath?: boolean): ProgramWithSourceTexts { + const host = createTestCompilerHost(texts, options.target!, /*oldProgram*/ undefined, useGetSourceFileByPath); + const program = ts.createProgram(rootNames, options, host) as ProgramWithSourceTexts; + program.sourceTexts = texts; + program.host = host; + return program; +} + +export function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: readonly string[], options: ts.CompilerOptions, updater: (files: NamedSourceText[]) => void, newTexts?: NamedSourceText[], useGetSourceFileByPath?: boolean) { + if (!newTexts) { + newTexts = oldProgram.sourceTexts!.slice(0); + } + updater(newTexts); + const host = createTestCompilerHost(newTexts, options.target!, oldProgram, useGetSourceFileByPath); + const program = ts.createProgram(rootNames, options, host, oldProgram) as ProgramWithSourceTexts; + program.sourceTexts = newTexts; + program.host = host; + return program; +} + +export function updateProgramText(files: readonly NamedSourceText[], fileName: string, newProgramText: string) { + const file = ts.find(files, f => f.name === fileName)!; + file.text = file.text.updateProgram(newProgramText); +} + +export function checkResolvedTypeDirective(actual: ts.ResolvedTypeReferenceDirective, expected: ts.ResolvedTypeReferenceDirective) { + assert.equal(actual.resolvedFileName, expected.resolvedFileName, `'resolvedFileName': expected '${actual.resolvedFileName}' to be equal to '${expected.resolvedFileName}'`); + assert.equal(actual.primary, expected.primary, `'primary': expected '${actual.primary}' to be equal to '${expected.primary}'`); + return true; +} + +function checkCache(caption: string, program: ts.Program, fileName: string, expectedContent: ts.ESMap | undefined, getCache: (f: ts.SourceFile) => ts.ModeAwareCache | undefined, entryChecker: (expected: T, original: T) => boolean): void { + const file = program.getSourceFile(fileName); + assert.isTrue(file !== undefined, `cannot find file ${fileName}`); + const cache = getCache(file!); + if (expectedContent === undefined) { + assert.isTrue(cache === undefined, `expected ${caption} to be undefined`); + } + else { + assert.isTrue(cache !== undefined, `expected ${caption} to be set`); + assert.isTrue(mapEqualToCache(expectedContent, cache!, entryChecker), `contents of ${caption} did not match the expected contents.`); + } +} + +/** True if the maps have the same keys and values. */ +function mapEqualToCache(left: ts.ESMap, right: ts.ModeAwareCache, valuesAreEqual?: (left: T, right: T) => boolean): boolean { + if (left as any === right) return true; // given the type mismatch (the tests never pass a cache), this'll never be true + if (!left || !right) return false; + const someInLeftHasNoMatch = ts.forEachEntry(left, (leftValue, leftKey) => { + if (!right.has(leftKey, /*mode*/ undefined)) return true; + const rightValue = right.get(leftKey, /*mode*/ undefined)!; + return !(valuesAreEqual ? valuesAreEqual(leftValue, rightValue) : leftValue === rightValue); + }); + if (someInLeftHasNoMatch) return false; + let someInRightHasNoMatch = false; + right.forEach((_, rightKey) => someInRightHasNoMatch = someInRightHasNoMatch || !left.has(rightKey)); + return !someInRightHasNoMatch; +} + +export function checkResolvedModulesCache(program: ts.Program, fileName: string, expectedContent: ts.ESMap | undefined): void { + checkCache("resolved modules", program, fileName, expectedContent, f => f.resolvedModules, ts.checkResolvedModule); +} + +export function checkResolvedTypeDirectivesCache(program: ts.Program, fileName: string, expectedContent: ts.ESMap | undefined): void { + checkCache("resolved type directives", program, fileName, expectedContent, f => f.resolvedTypeReferenceDirectiveNames, checkResolvedTypeDirective); +} + +export function createResolvedModule(resolvedFileName: string, isExternalLibraryImport = false): ts.ResolvedModuleFull { + return { resolvedFileName, extension: ts.extensionFromPath(resolvedFileName), isExternalLibraryImport }; +} + +export function checkResolvedModule(actual: ts.ResolvedModuleFull | undefined, expected: ts.ResolvedModuleFull | undefined): boolean { + if (!expected) { + if (actual) { + assert.fail(actual, expected, "expected resolved module to be undefined"); + return false; + } + return true; + } + else if (!actual) { + assert.fail(actual, expected, "expected resolved module to be defined"); + return false; + } + + assert.isTrue(actual.resolvedFileName === expected.resolvedFileName, `'resolvedFileName': expected '${actual.resolvedFileName}' to be equal to '${expected.resolvedFileName}'`); + assert.isTrue(actual.extension === expected.extension, `'ext': expected '${actual.extension}' to be equal to '${expected.extension}'`); + assert.isTrue(actual.isExternalLibraryImport === expected.isExternalLibraryImport, `'isExternalLibraryImport': expected '${actual.isExternalLibraryImport}' to be equal to '${expected.isExternalLibraryImport}'`); + return true; +} + +export function checkResolvedModuleWithFailedLookupLocations(actual: ts.ResolvedModuleWithFailedLookupLocations, expectedResolvedModule: ts.ResolvedModuleFull, expectedFailedLookupLocations: string[]): void { + assert.isTrue(actual.resolvedModule !== undefined, "module should be resolved"); + checkResolvedModule(actual.resolvedModule, expectedResolvedModule); + assert.deepEqual(actual.failedLookupLocations, expectedFailedLookupLocations, `Failed lookup locations should match - expected has ${expectedFailedLookupLocations.length}, actual has ${actual.failedLookupLocations.length}`); +} diff --git a/src/testRunner/unittests/moduleResolution.ts b/src/testRunner/unittests/moduleResolution.ts index 90c49fbb881f8..7f2c76fedd37c 100644 --- a/src/testRunner/unittests/moduleResolution.ts +++ b/src/testRunner/unittests/moduleResolution.ts @@ -1,34 +1,6 @@ import * as ts from "../_namespaces/ts"; import * as Harness from "../_namespaces/Harness"; - -export function checkResolvedModule(actual: ts.ResolvedModuleFull | undefined, expected: ts.ResolvedModuleFull | undefined): boolean { - if (!expected) { - if (actual) { - assert.fail(actual, expected, "expected resolved module to be undefined"); - return false; - } - return true; - } - else if (!actual) { - assert.fail(actual, expected, "expected resolved module to be defined"); - return false; - } - - assert.isTrue(actual.resolvedFileName === expected.resolvedFileName, `'resolvedFileName': expected '${actual.resolvedFileName}' to be equal to '${expected.resolvedFileName}'`); - assert.isTrue(actual.extension === expected.extension, `'ext': expected '${actual.extension}' to be equal to '${expected.extension}'`); - assert.isTrue(actual.isExternalLibraryImport === expected.isExternalLibraryImport, `'isExternalLibraryImport': expected '${actual.isExternalLibraryImport}' to be equal to '${expected.isExternalLibraryImport}'`); - return true; -} - -export function checkResolvedModuleWithFailedLookupLocations(actual: ts.ResolvedModuleWithFailedLookupLocations, expectedResolvedModule: ts.ResolvedModuleFull, expectedFailedLookupLocations: string[]): void { - assert.isTrue(actual.resolvedModule !== undefined, "module should be resolved"); - checkResolvedModule(actual.resolvedModule, expectedResolvedModule); - assert.deepEqual(actual.failedLookupLocations, expectedFailedLookupLocations, `Failed lookup locations should match - expected has ${expectedFailedLookupLocations.length}, actual has ${actual.failedLookupLocations.length}`); -} - -export function createResolvedModule(resolvedFileName: string, isExternalLibraryImport = false): ts.ResolvedModuleFull { - return { resolvedFileName, extension: ts.extensionFromPath(resolvedFileName), isExternalLibraryImport }; -} +import { checkResolvedModule, checkResolvedModuleWithFailedLookupLocations, createResolvedModule } from "./helpers"; interface File { name: string; diff --git a/src/testRunner/unittests/reuseProgramStructure.ts b/src/testRunner/unittests/reuseProgramStructure.ts index 7891de1f116ba..b597538f088dc 100644 --- a/src/testRunner/unittests/reuseProgramStructure.ts +++ b/src/testRunner/unittests/reuseProgramStructure.ts @@ -1,215 +1,6 @@ import * as ts from "../_namespaces/ts"; -const enum ChangedPart { - references = 1 << 0, - importsAndExports = 1 << 1, - program = 1 << 2 -} - -const newLine = "\r\n"; - -interface SourceFileWithText extends ts.SourceFile { - sourceText?: SourceText; -} - -export interface NamedSourceText { - name: string; - text: SourceText; -} - -export interface ProgramWithSourceTexts extends ts.Program { - sourceTexts?: readonly NamedSourceText[]; - host: TestCompilerHost; -} - -interface TestCompilerHost extends ts.CompilerHost { - getTrace(): string[]; -} - -export class SourceText implements ts.IScriptSnapshot { - private fullText: string | undefined; - - constructor(private references: string, - private importsAndExports: string, - private program: string, - private changedPart: ChangedPart = 0, - private version = 0) { - } - - static New(references: string, importsAndExports: string, program: string): SourceText { - ts.Debug.assert(references !== undefined); - ts.Debug.assert(importsAndExports !== undefined); - ts.Debug.assert(program !== undefined); - return new SourceText(references + newLine, importsAndExports + newLine, program || ""); - } - - public getVersion(): number { - return this.version; - } - - public updateReferences(newReferences: string): SourceText { - ts.Debug.assert(newReferences !== undefined); - return new SourceText(newReferences + newLine, this.importsAndExports, this.program, this.changedPart | ChangedPart.references, this.version + 1); - } - public updateImportsAndExports(newImportsAndExports: string): SourceText { - ts.Debug.assert(newImportsAndExports !== undefined); - return new SourceText(this.references, newImportsAndExports + newLine, this.program, this.changedPart | ChangedPart.importsAndExports, this.version + 1); - } - public updateProgram(newProgram: string): SourceText { - ts.Debug.assert(newProgram !== undefined); - return new SourceText(this.references, this.importsAndExports, newProgram, this.changedPart | ChangedPart.program, this.version + 1); - } - - public getFullText() { - return this.fullText || (this.fullText = this.references + this.importsAndExports + this.program); - } - - public getText(start: number, end: number): string { - return this.getFullText().substring(start, end); - } - - getLength(): number { - return this.getFullText().length; - } - - getChangeRange(oldSnapshot: ts.IScriptSnapshot): ts.TextChangeRange { - const oldText = oldSnapshot as SourceText; - let oldSpan: ts.TextSpan; - let newLength: number; - switch (oldText.changedPart ^ this.changedPart) { - case ChangedPart.references: - oldSpan = ts.createTextSpan(0, oldText.references.length); - newLength = this.references.length; - break; - case ChangedPart.importsAndExports: - oldSpan = ts.createTextSpan(oldText.references.length, oldText.importsAndExports.length); - newLength = this.importsAndExports.length; - break; - case ChangedPart.program: - oldSpan = ts.createTextSpan(oldText.references.length + oldText.importsAndExports.length, oldText.program.length); - newLength = this.program.length; - break; - default: - return ts.Debug.fail("Unexpected change"); - } - - return ts.createTextChangeRange(oldSpan, newLength); - } -} - -function createSourceFileWithText(fileName: string, sourceText: SourceText, target: ts.ScriptTarget) { - const file = ts.createSourceFile(fileName, sourceText.getFullText(), target) as SourceFileWithText; - file.sourceText = sourceText; - file.version = "" + sourceText.getVersion(); - return file; -} - -export function createTestCompilerHost(texts: readonly NamedSourceText[], target: ts.ScriptTarget, oldProgram?: ProgramWithSourceTexts, useGetSourceFileByPath?: boolean) { - const files = ts.arrayToMap(texts, t => t.name, t => { - if (oldProgram) { - let oldFile = oldProgram.getSourceFile(t.name) as SourceFileWithText; - if (oldFile && oldFile.redirectInfo) { - oldFile = oldFile.redirectInfo.unredirected; - } - if (oldFile && oldFile.sourceText!.getVersion() === t.text.getVersion()) { - return oldFile; - } - } - return createSourceFileWithText(t.name, t.text, target); - }); - const useCaseSensitiveFileNames = ts.sys && ts.sys.useCaseSensitiveFileNames; - const getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames); - const trace: string[] = []; - const result: TestCompilerHost = { - trace: s => trace.push(s), - getTrace: () => trace, - getSourceFile: fileName => files.get(fileName), - getDefaultLibFileName: () => "lib.d.ts", - writeFile: ts.notImplemented, - getCurrentDirectory: () => "", - getDirectories: () => [], - getCanonicalFileName, - useCaseSensitiveFileNames: () => useCaseSensitiveFileNames, - getNewLine: () => ts.sys ? ts.sys.newLine : newLine, - fileExists: fileName => files.has(fileName), - readFile: fileName => { - const file = files.get(fileName); - return file && file.text; - }, - }; - if (useGetSourceFileByPath) { - const filesByPath = ts.mapEntries(files, (fileName, file) => [ts.toPath(fileName, "", getCanonicalFileName), file]); - result.getSourceFileByPath = (_fileName, path) => filesByPath.get(path); - } - return result; -} - -export function newProgram(texts: NamedSourceText[], rootNames: string[], options: ts.CompilerOptions, useGetSourceFileByPath?: boolean): ProgramWithSourceTexts { - const host = createTestCompilerHost(texts, options.target!, /*oldProgram*/ undefined, useGetSourceFileByPath); - const program = ts.createProgram(rootNames, options, host) as ProgramWithSourceTexts; - program.sourceTexts = texts; - program.host = host; - return program; -} - -export function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: readonly string[], options: ts.CompilerOptions, updater: (files: NamedSourceText[]) => void, newTexts?: NamedSourceText[], useGetSourceFileByPath?: boolean) { - if (!newTexts) { - newTexts = oldProgram.sourceTexts!.slice(0); - } - updater(newTexts); - const host = createTestCompilerHost(newTexts, options.target!, oldProgram, useGetSourceFileByPath); - const program = ts.createProgram(rootNames, options, host, oldProgram) as ProgramWithSourceTexts; - program.sourceTexts = newTexts; - program.host = host; - return program; -} - -export function updateProgramText(files: readonly NamedSourceText[], fileName: string, newProgramText: string) { - const file = ts.find(files, f => f.name === fileName)!; - file.text = file.text.updateProgram(newProgramText); -} - -function checkResolvedTypeDirective(actual: ts.ResolvedTypeReferenceDirective, expected: ts.ResolvedTypeReferenceDirective) { - assert.equal(actual.resolvedFileName, expected.resolvedFileName, `'resolvedFileName': expected '${actual.resolvedFileName}' to be equal to '${expected.resolvedFileName}'`); - assert.equal(actual.primary, expected.primary, `'primary': expected '${actual.primary}' to be equal to '${expected.primary}'`); - return true; -} - -function checkCache(caption: string, program: ts.Program, fileName: string, expectedContent: ts.ESMap | undefined, getCache: (f: ts.SourceFile) => ts.ModeAwareCache | undefined, entryChecker: (expected: T, original: T) => boolean): void { - const file = program.getSourceFile(fileName); - assert.isTrue(file !== undefined, `cannot find file ${fileName}`); - const cache = getCache(file!); - if (expectedContent === undefined) { - assert.isTrue(cache === undefined, `expected ${caption} to be undefined`); - } - else { - assert.isTrue(cache !== undefined, `expected ${caption} to be set`); - assert.isTrue(mapEqualToCache(expectedContent, cache!, entryChecker), `contents of ${caption} did not match the expected contents.`); - } -} - -/** True if the maps have the same keys and values. */ -function mapEqualToCache(left: ts.ESMap, right: ts.ModeAwareCache, valuesAreEqual?: (left: T, right: T) => boolean): boolean { - if (left as any === right) return true; // given the type mismatch (the tests never pass a cache), this'll never be true - if (!left || !right) return false; - const someInLeftHasNoMatch = ts.forEachEntry(left, (leftValue, leftKey) => { - if (!right.has(leftKey, /*mode*/ undefined)) return true; - const rightValue = right.get(leftKey, /*mode*/ undefined)!; - return !(valuesAreEqual ? valuesAreEqual(leftValue, rightValue) : leftValue === rightValue); - }); - if (someInLeftHasNoMatch) return false; - let someInRightHasNoMatch = false; - right.forEach((_, rightKey) => someInRightHasNoMatch = someInRightHasNoMatch || !left.has(rightKey)); - return !someInRightHasNoMatch; -} - -function checkResolvedModulesCache(program: ts.Program, fileName: string, expectedContent: ts.ESMap | undefined): void { - checkCache("resolved modules", program, fileName, expectedContent, f => f.resolvedModules, ts.checkResolvedModule); -} - -function checkResolvedTypeDirectivesCache(program: ts.Program, fileName: string, expectedContent: ts.ESMap | undefined): void { - checkCache("resolved type directives", program, fileName, expectedContent, f => f.resolvedTypeReferenceDirectiveNames, checkResolvedTypeDirective); -} +import { checkResolvedModulesCache, checkResolvedTypeDirectivesCache, createTestCompilerHost, NamedSourceText, newLine, newProgram, ProgramWithSourceTexts, SourceText, TestCompilerHost, updateProgram, updateProgramText } from "./helpers"; describe("unittests:: Reuse program structure:: General", () => { const target = ts.ScriptTarget.Latest; diff --git a/src/testRunner/unittests/tsserver/dynamicFiles.ts b/src/testRunner/unittests/tsserver/dynamicFiles.ts index 19398777e39e6..8ef9fd038b405 100644 --- a/src/testRunner/unittests/tsserver/dynamicFiles.ts +++ b/src/testRunner/unittests/tsserver/dynamicFiles.ts @@ -1,9 +1,5 @@ import * as ts from "../../_namespaces/ts"; - -export function verifyDynamic(service: ts.server.ProjectService, path: string) { - const info = ts.Debug.checkDefined(service.filenameToScriptInfo.get(path), `Expected ${path} in :: ${JSON.stringify(ts.arrayFrom(service.filenameToScriptInfo.entries(), ([key, f]) => ({ key, fileName: f.fileName, path: f.path })))}`); - assert.isTrue(info.isDynamic); -} +import { verifyDynamic } from "./helpers"; function verifyPathRecognizedAsDynamic(path: string) { const file: ts.projectSystem.File = { diff --git a/src/testRunner/unittests/tsserver/helpers.ts b/src/testRunner/unittests/tsserver/helpers.ts index 5c451157f277c..055ca6ae6c631 100644 --- a/src/testRunner/unittests/tsserver/helpers.ts +++ b/src/testRunner/unittests/tsserver/helpers.ts @@ -938,3 +938,15 @@ export function verifyGetErrScenario(scenario: VerifyGetErrScenario) { verifyErrorsUsingGeterrForProject(scenario); verifyErrorsUsingSyncMethods(scenario); } + +export function verifyDynamic(service: ts.server.ProjectService, path: string) { + const info = ts.Debug.checkDefined(service.filenameToScriptInfo.get(path), `Expected ${path} in :: ${JSON.stringify(ts.arrayFrom(service.filenameToScriptInfo.entries(), ([key, f]) => ({ key, fileName: f.fileName, path: f.path })))}`); + assert.isTrue(info.isDynamic); +} + +export function createHostWithSolutionBuild(files: readonly ts.TestFSWithWatch.FileOrFolderOrSymLink[], rootNames: readonly string[]) { + const host = ts.projectSystem.createServerHost(files); + // ts build should succeed + ts.tscWatch.ensureErrorFreeBuild(host, rootNames); + return host; +} diff --git a/src/testRunner/unittests/tsserver/projectReferences.ts b/src/testRunner/unittests/tsserver/projectReferences.ts index 85ca59c24f68d..d03e2167deb99 100644 --- a/src/testRunner/unittests/tsserver/projectReferences.ts +++ b/src/testRunner/unittests/tsserver/projectReferences.ts @@ -1,11 +1,5 @@ import * as ts from "../../_namespaces/ts"; - -export function createHostWithSolutionBuild(files: readonly ts.TestFSWithWatch.FileOrFolderOrSymLink[], rootNames: readonly string[]) { - const host = ts.projectSystem.createServerHost(files); - // ts build should succeed - ts.tscWatch.ensureErrorFreeBuild(host, rootNames); - return host; -} +import { createHostWithSolutionBuild } from "./helpers"; describe("unittests:: tsserver:: with project references and tsbuild", () => { describe("with container project", () => {