diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7f20c5421285f..9d4cf8914969d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -51,6 +51,7 @@ namespace ts { const emitResolver = createResolver(); const undefinedSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "undefined"); + undefinedSymbol.declarations = []; const argumentsSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "arguments"); const checker: TypeChecker = { @@ -516,6 +517,12 @@ namespace ts { } switch (location.kind) { case SyntaxKind.SourceFile: + if ((location).package) { + if (hasProperty((location).package.symbols, name)) { + result = (location).package.symbols[name]; + break loop; + } + } if (!isExternalOrCommonJsModule(location)) break; case SyntaxKind.ModuleDeclaration: const moduleExports = getSymbolOfNode(location).exports; @@ -1040,7 +1047,8 @@ namespace ts { const isRelative = isExternalModuleNameRelative(moduleName); if (!isRelative) { - const symbol = getSymbol(globals, "\"" + moduleName + "\"", SymbolFlags.ValueModule); + const file = getSourceFileOfNode(location); + const symbol = getSymbol(file.package ? file.package.symbols : globals, "\"" + moduleName + "\"", SymbolFlags.ValueModule); if (symbol) { return symbol; } @@ -1052,6 +1060,12 @@ namespace ts { if (sourceFile.symbol) { return sourceFile.symbol; } + else if (sourceFile.package && !isRelative) { + const symbol = getSymbol(sourceFile.package.symbols, "\"" + moduleName + "\"", SymbolFlags.ValueModule); + if (symbol) { + return symbol; + } + } error(moduleReferenceLiteral, Diagnostics.File_0_is_not_a_module, sourceFile.fileName); return; } @@ -1248,6 +1262,11 @@ namespace ts { } switch (location.kind) { case SyntaxKind.SourceFile: + if ((location).package) { + if (result = callback((location).package.symbols)) { + return result; + } + } if (!isExternalOrCommonJsModule(location)) { break; } @@ -14478,6 +14497,9 @@ namespace ts { switch (location.kind) { case SyntaxKind.SourceFile: + if ((location).package) { + copySymbols((location).package.symbols, meaning); + } if (!isExternalOrCommonJsModule(location)) { break; } @@ -15156,6 +15178,10 @@ namespace ts { return hasProperty(globals, name); } + function hasPackageInternalName(file: SourceFile, name: string): boolean { + return file.package && hasProperty(file.package.symbols, name); + } + function getReferencedValueSymbol(reference: Identifier): Symbol { return getNodeLinks(reference).resolvedSymbol || resolveName(reference, reference.text, SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, @@ -15190,6 +15216,7 @@ namespace ts { isNestedRedeclaration, isValueAliasDeclaration, hasGlobalName, + hasPackageInternalName, isReferencedAliasDeclaration, getNodeCheckFlags, isTopLevelValueImportEqualsWithEntityName, @@ -15225,10 +15252,25 @@ namespace ts { bindSourceFile(file, compilerOptions); }); - // Initialize global symbol table + const packages: Map = {}; + + // Initialize package/global symbol table(s) forEach(host.getSourceFiles(), file => { if (!isExternalOrCommonJsModule(file)) { - mergeSymbolTable(globals, file.locals); + if (file.package) { + // Dedupe/merge packages + const id = file.package.packagePath; + if (!packages[id]) { + packages[id] = file.package; + } + else { + file.package = packages[id]; + } + mergeSymbolTable(file.package.symbols, file.locals); + } + else { + mergeSymbolTable(globals, file.locals); + } } }); @@ -15283,6 +15325,11 @@ namespace ts { } anyArrayType = createArrayType(anyType); + + // Once all packages are merged and global scope is setup, merge global scope into each package + forEachValue(packages, package => { + mergeSymbolTable(package.symbols, globals); + }); } function createInstantiatedPromiseLikeType(): ObjectType { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 79f0251c5651f..7b17c1e265030 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -68,6 +68,12 @@ namespace ts { return getCanonicalFileName(nonCanonicalizedPath); } + export function convertToRelativePath(absoluteOrRelativePath: string, basePath: string, getCanonicalFileName: (path: string) => string): string { + return !isRootedDiskPath(absoluteOrRelativePath) + ? absoluteOrRelativePath + : getRelativePathToDirectoryOrUrl(basePath, absoluteOrRelativePath, basePath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); + } + export const enum Comparison { LessThan = -1, EqualTo = 0, @@ -624,6 +630,21 @@ namespace ts { } } + /** + * Given a path to a file within a module, returns a path uniqely identifying that module + */ + export function moduleFilePathToIdentifyingPath(path: Path, currentDirectory: string, getCanonicalFileName: (filename: string) => string): string { + const components = normalizedPathComponents(normalizeSlashes(path), getRootLength(path)); + let part: string; + let lastPart: string; + while (lastPart = part, part = components.pop()) { + if (part === "node_modules") { + return convertToRelativePath(getNormalizedPathFromPathComponents([...components, lastPart]), currentDirectory, getCanonicalFileName); + } + } + return convertToRelativePath(path, currentDirectory, getCanonicalFileName); + } + function getNormalizedPathComponentsOfUrl(url: string) { // Get root length of http://www.website.com/folder1/foler2/ // In this example the root is: http://www.website.com/ diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 62661706373fa..b05f989609190 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1712,7 +1712,7 @@ "category": "Error", "code": 2653 }, - "Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition.": { + "Exported external package typings file cannot contain script file tripleslash references. Please contact the package author to update the package definition.": { "category": "Error", "code": 2654 }, @@ -2277,7 +2277,10 @@ "category": "Error", "code": 6063 }, - + "File '{0}' was referenced by a package '{1}' but is already included by package '{2}'.": { + "category": "Error", + "code": 6064 + }, "Enables experimental support for ES7 decorators.": { "category": "Message", "code": 6065 diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index b4d2e02e4f068..bd7a8ac54b778 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -621,6 +621,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi function isUniqueName(name: string): boolean { return !resolver.hasGlobalName(name) && + !resolver.hasPackageInternalName(currentSourceFile, name) && !hasProperty(currentFileIdentifiers, name) && !hasProperty(generatedNameSet, name); } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 6139dda0013d6..4ec3861072969 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -53,16 +53,14 @@ namespace ts { if (getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) { const failedLookupLocations: string[] = []; const candidate = normalizePath(combinePaths(containingDirectory, moduleName)); - let resolvedFileName = loadNodeModuleFromFile(supportedExtensions, candidate, failedLookupLocations, host); + const resolvedFileName = loadNodeModuleFromFile(supportedExtensions, candidate, failedLookupLocations, host); if (resolvedFileName) { return { resolvedModule: { resolvedFileName }, failedLookupLocations }; } - resolvedFileName = loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, host); - return resolvedFileName - ? { resolvedModule: { resolvedFileName }, failedLookupLocations } - : { resolvedModule: undefined, failedLookupLocations }; + const res = loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, host, /*mustBePackage*/false); + return { resolvedModule: res, failedLookupLocations }; } else { return loadModuleFromNodeModules(moduleName, containingDirectory, host); @@ -84,7 +82,7 @@ namespace ts { } } - function loadNodeModuleFromDirectory(extensions: string[], candidate: string, failedLookupLocation: string[], host: ModuleResolutionHost): string { + function loadNodeModuleFromDirectory(extensions: string[], candidate: string, failedLookupLocation: string[], host: ModuleResolutionHost, mustBePackage: boolean): ResolvedModule { const packageJsonPath = combinePaths(candidate, "package.json"); if (host.fileExists(packageJsonPath)) { @@ -102,7 +100,7 @@ namespace ts { if (jsonContent.typings) { const result = loadNodeModuleFromFile(extensions, normalizePath(combinePaths(candidate, jsonContent.typings)), failedLookupLocation, host); if (result) { - return result; + return { resolvedFileName: result, packageRoot: packageJsonPath }; } } } @@ -111,7 +109,10 @@ namespace ts { failedLookupLocation.push(packageJsonPath); } - return loadNodeModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocation, host); + const result = loadNodeModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocation, host); + if (result) { + return { resolvedFileName: result, packageRoot: mustBePackage ? result : undefined }; + } } function loadModuleFromNodeModules(moduleName: string, directory: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations { @@ -122,15 +123,15 @@ namespace ts { if (baseName !== "node_modules") { const nodeModulesFolder = combinePaths(directory, "node_modules"); const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName)); - // Load only typescript files irrespective of allowJs option if loading from node modules - let result = loadNodeModuleFromFile(supportedTypeScriptExtensions, candidate, failedLookupLocations, host); + const result = loadNodeModuleFromFile(supportedTypeScriptExtensions, candidate, failedLookupLocations, host); + if (result) { - return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations }; + return { resolvedModule: { resolvedFileName: result, packageRoot: result }, failedLookupLocations }; } - result = loadNodeModuleFromDirectory(supportedTypeScriptExtensions, candidate, failedLookupLocations, host); - if (result) { - return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations }; + const res = loadNodeModuleFromDirectory(supportedTypeScriptExtensions, candidate, failedLookupLocations, host, /*mustBePackage*/ true); + if (res) { + return { resolvedModule: res, failedLookupLocations }; } } @@ -501,7 +502,7 @@ namespace ts { const resolutionChanged = oldResolution ? !newResolution || oldResolution.resolvedFileName !== newResolution.resolvedFileName || - !!oldResolution.isExternalLibraryImport !== !!newResolution.isExternalLibraryImport + !!oldResolution.packageRoot !== !!newResolution.packageRoot : newResolution; if (resolutionChanged) { @@ -951,7 +952,7 @@ namespace ts { diagnostic = Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1; diagnosticArgument = [fileName, "'" + supportedExtensions.join("', '") + "'"]; } - else if (!findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd)) { + else if (!findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd, refFile && refFile.package)) { diagnostic = Diagnostics.File_0_not_found; diagnosticArgument = [fileName]; } @@ -961,13 +962,13 @@ namespace ts { } } else { - const nonTsFile: SourceFile = options.allowNonTsExtensions && findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd); + const nonTsFile: SourceFile = options.allowNonTsExtensions && findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd, refFile && refFile.package); if (!nonTsFile) { if (options.allowNonTsExtensions) { diagnostic = Diagnostics.File_0_not_found; diagnosticArgument = [fileName]; } - else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, toPath(fileName + extension, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd))) { + else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, toPath(fileName + extension, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd, refFile && refFile.package))) { diagnostic = Diagnostics.File_0_not_found; fileName += ".ts"; diagnosticArgument = [fileName]; @@ -996,7 +997,7 @@ namespace ts { } // Get source file from normalized fileName - function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile { + function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number, package?: PackageDescriptor): SourceFile { if (filesByName.contains(path)) { const file = filesByName.get(path); // try to check if we've already seen this file but with a different casing in path @@ -1004,7 +1005,12 @@ namespace ts { if (file && options.forceConsistentCasingInFileNames && getNormalizedAbsolutePath(file.fileName, currentDirectory) !== getNormalizedAbsolutePath(fileName, currentDirectory)) { reportFileNamesDifferOnlyInCasingError(fileName, file.fileName, refFile, refPos, refEnd); } - + const newLocation = package && package.packagePath; + const oldLocation = file && file.package && file.package.packagePath; + // Error if we've already encounted this file but via a different package + if (newLocation !== oldLocation) { + fileProcessingDiagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos, Diagnostics.File_0_was_referenced_by_a_package_1_but_is_already_included_by_package_2, fileName, newLocation, oldLocation)); + } return file; } @@ -1018,10 +1024,10 @@ namespace ts { fileProcessingDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage)); } }); - filesByName.set(path, file); if (file) { file.path = path; + file.package = package; if (host.useCaseSensitiveFileNames()) { // for case-sensitive file systems check if we've already seen some file with similar filename ignoring case @@ -1058,6 +1064,9 @@ namespace ts { function processReferencedFiles(file: SourceFile, basePath: string) { forEach(file.referencedFiles, ref => { const referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName); + if (file.package && !fileExtensionIs(referencedFileName, ".d.ts")) { + fileProcessingDiagnostics.add(createFileDiagnostic(file, ref.pos, ref.end - ref.pos, Diagnostics.Exported_external_package_typings_file_cannot_contain_script_file_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition)); + } processSourceFile(referencedFileName, /*isDefaultLib*/ false, file, ref.pos, ref.end); }); } @@ -1076,18 +1085,9 @@ namespace ts { const resolution = resolutions[i]; setResolvedModule(file, moduleNames[i], resolution); if (resolution && !options.noResolve) { - const importedFile = findSourceFile(resolution.resolvedFileName, toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), /*isDefaultLib*/ false, file, skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); - - if (importedFile && resolution.isExternalLibraryImport) { - if (!isExternalModule(importedFile)) { - const start = getTokenPosOfNode(file.imports[i], file); - fileProcessingDiagnostics.add(createFileDiagnostic(file, start, file.imports[i].end - start, Diagnostics.Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition, importedFile.fileName)); - } - else if (importedFile.referencedFiles.length) { - const firstRef = importedFile.referencedFiles[0]; - fileProcessingDiagnostics.add(createFileDiagnostic(importedFile, firstRef.pos, firstRef.end - firstRef.pos, Diagnostics.Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition)); - } - } + const filePath = toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName); + const package = resolution.packageRoot ? {packagePath: moduleFilePathToIdentifyingPath(filePath, currentDirectory, getCanonicalFileName), symbols: {} as SymbolTable} : file.package; + findSourceFile(resolution.resolvedFileName, filePath, /*isDefaultLib*/ false, file, skipTrivia(file.text, file.imports[i].pos), file.imports[i].end, package); } } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f8b26ddaa6dda..b434f17227fe0 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1506,6 +1506,10 @@ namespace ts { isBracketed: boolean; } + export interface PackageDescriptor extends Scope { + packagePath: string; // This should be either the path to a named .d.ts, an index.d.ts, a package.json, or a directory which uniqely identifies the package + } + export interface AmdDependency { path: string; name: string; @@ -1526,6 +1530,9 @@ namespace ts { referencedFiles: FileReference[]; languageVariant: LanguageVariant; + /* @internal */ + package?: PackageDescriptor; + // this map is used by transpiler to supply alternative names for dependencies (i.e. in case of bundling) /* @internal */ renamedDependencies?: Map; @@ -1570,6 +1577,10 @@ namespace ts { /* @internal */ imports: LiteralExpression[]; } + export interface Scope { + symbols: SymbolTable; // Locals associated with node (initialized by binding) + } + export interface ScriptReferenceHost { getCompilerOptions(): CompilerOptions; getSourceFile(fileName: string): SourceFile; @@ -1861,6 +1872,7 @@ namespace ts { /* @internal */ export interface EmitResolver { hasGlobalName(name: string): boolean; + hasPackageInternalName(node: SourceFile, name: string): boolean; getReferencedExportContainer(node: Identifier): SourceFile | ModuleDeclaration | EnumDeclaration; getReferencedImportDeclaration(node: Identifier): Declaration; getReferencedNestedRedeclaration(node: Identifier): Declaration; @@ -2611,9 +2623,8 @@ namespace ts { * Denotes if 'resolvedFileName' is isExternalLibraryImport and thus should be proper external module: * - be a .d.ts file * - use top level imports\exports - * - don't use tripleslash references */ - isExternalLibraryImport?: boolean; + packageRoot?: string; } export interface ResolvedModuleWithFailedLookupLocations { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 66daf4cf3115e..c8ead64a6c9fb 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2449,12 +2449,6 @@ namespace ts { return result; } - export function convertToRelativePath(absoluteOrRelativePath: string, basePath: string, getCanonicalFileName: (path: string) => string): string { - return !isRootedDiskPath(absoluteOrRelativePath) - ? absoluteOrRelativePath - : getRelativePathToDirectoryOrUrl(basePath, absoluteOrRelativePath, basePath, getCanonicalFileName, /* isAbsolutePathAnUrl */ false); - } - const carriageReturnLineFeed = "\r\n"; const lineFeed = "\n"; export function getNewLineCharacter(options: CompilerOptions): string { diff --git a/tests/baselines/reference/nodeResolution10.errors.txt b/tests/baselines/reference/nodeResolution10.errors.txt new file mode 100644 index 0000000000000..baa961f1d0858 --- /dev/null +++ b/tests/baselines/reference/nodeResolution10.errors.txt @@ -0,0 +1,43 @@ +tests/cases/compiler/b.ts(9,16): error TS2339: Property 'otherMember' does not exist on type 'Foo'. +tests/cases/compiler/b.ts(13,22): error TS2339: Property 'staticMember' does not exist on type 'Foo'. +tests/cases/compiler/node_modules/a/index.d.ts(4,39): error TS2339: Property 'otherMember' does not exist on type 'Foo'. + + +==== tests/cases/compiler/b.ts (2 errors) ==== + import y = require("a"); + + interface Foo { + otherMember: number; + } + + let foo: number = y.foo; + let bigFoo = y.dummy; + let n = bigFoo.otherMember; // should error + ~~~~~~~~~~~ +!!! error TS2339: Property 'otherMember' does not exist on type 'Foo'. + + let foo2: Foo; + let t: number = foo2.otherMember; + let e: string = foo2.staticMember; // should error + ~~~~~~~~~~~~ +!!! error TS2339: Property 'staticMember' does not exist on type 'Foo'. + +==== tests/cases/compiler/node_modules/a/ref.d.ts (0 errors) ==== + + interface Foo { + staticMember: string; + } + + declare module "internal" { + export var foo: number; + } + +==== tests/cases/compiler/node_modules/a/index.d.ts (1 errors) ==== + /// + export var dummy: Foo; + export var dummyMember: typeof dummy.staticMember; + export var dummyMember2: typeof dummy.otherMember; // should error + ~~~~~~~~~~~ +!!! error TS2339: Property 'otherMember' does not exist on type 'Foo'. + export * from "internal"; + \ No newline at end of file diff --git a/tests/baselines/reference/nodeResolution10.js b/tests/baselines/reference/nodeResolution10.js new file mode 100644 index 0000000000000..fa5965441eb4d --- /dev/null +++ b/tests/baselines/reference/nodeResolution10.js @@ -0,0 +1,44 @@ +//// [tests/cases/compiler/nodeResolution10.ts] //// + +//// [ref.d.ts] + +interface Foo { + staticMember: string; +} + +declare module "internal" { + export var foo: number; +} + +//// [index.d.ts] +/// +export var dummy: Foo; +export var dummyMember: typeof dummy.staticMember; +export var dummyMember2: typeof dummy.otherMember; // should error +export * from "internal"; + +//// [b.ts] +import y = require("a"); + +interface Foo { + otherMember: number; +} + +let foo: number = y.foo; +let bigFoo = y.dummy; +let n = bigFoo.otherMember; // should error + +let foo2: Foo; +let t: number = foo2.otherMember; +let e: string = foo2.staticMember; // should error + + +//// [b.js] +"use strict"; +var y = require("a"); +var foo = y.foo; +var bigFoo = y.dummy; +var n = bigFoo.otherMember; // should error +var foo2; +var t = foo2.otherMember; +var e = foo2.staticMember; // should error diff --git a/tests/baselines/reference/nodeResolution11.errors.txt b/tests/baselines/reference/nodeResolution11.errors.txt new file mode 100644 index 0000000000000..12bc71400a183 --- /dev/null +++ b/tests/baselines/reference/nodeResolution11.errors.txt @@ -0,0 +1,39 @@ +tests/cases/compiler/b.ts(10,22): error TS2339: Property 'staticMember' does not exist on type 'Foo'. + + +==== tests/cases/compiler/b.ts (1 errors) ==== + /// + import y = require("a"); + + let foo: number = y.foo; + let bigFoo = y.dummy; + let n = bigFoo.otherMember; // global foo merged into package Foo, should be here + + let foo2: Foo; + let t: number = foo2.otherMember; + let e: string = foo2.staticMember; // should error, is global Foo + ~~~~~~~~~~~~ +!!! error TS2339: Property 'staticMember' does not exist on type 'Foo'. + +==== tests/cases/compiler/node_modules/a/ref.d.ts (0 errors) ==== + + interface Foo { + staticMember: string; + } + + declare module "internal" { + export var foo: number; + } + +==== tests/cases/compiler/node_modules/a/index.d.ts (0 errors) ==== + /// + export var dummy: Foo; + export var dummyMember: typeof dummy.staticMember; + export var dummyMember2: typeof dummy.otherMember; // global foo merged in, should be here + export * from "internal"; + +==== tests/cases/compiler/ref.d.ts (0 errors) ==== + interface Foo { + otherMember: number; + } + \ No newline at end of file diff --git a/tests/baselines/reference/nodeResolution11.js b/tests/baselines/reference/nodeResolution11.js new file mode 100644 index 0000000000000..b8ff6e2261c71 --- /dev/null +++ b/tests/baselines/reference/nodeResolution11.js @@ -0,0 +1,47 @@ +//// [tests/cases/compiler/nodeResolution11.ts] //// + +//// [ref.d.ts] + +interface Foo { + staticMember: string; +} + +declare module "internal" { + export var foo: number; +} + +//// [index.d.ts] +/// +export var dummy: Foo; +export var dummyMember: typeof dummy.staticMember; +export var dummyMember2: typeof dummy.otherMember; // global foo merged in, should be here +export * from "internal"; + +//// [ref.d.ts] +interface Foo { + otherMember: number; +} + +//// [b.ts] +/// +import y = require("a"); + +let foo: number = y.foo; +let bigFoo = y.dummy; +let n = bigFoo.otherMember; // global foo merged into package Foo, should be here + +let foo2: Foo; +let t: number = foo2.otherMember; +let e: string = foo2.staticMember; // should error, is global Foo + + +//// [b.js] +"use strict"; +/// +var y = require("a"); +var foo = y.foo; +var bigFoo = y.dummy; +var n = bigFoo.otherMember; // global foo merged into package Foo, should be here +var foo2; +var t = foo2.otherMember; +var e = foo2.staticMember; // should error, is global Foo diff --git a/tests/baselines/reference/nodeResolution12.js b/tests/baselines/reference/nodeResolution12.js new file mode 100644 index 0000000000000..ab6a7100d3010 --- /dev/null +++ b/tests/baselines/reference/nodeResolution12.js @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/nodeResolution12.ts] //// + +//// [index.d.ts] +import internal = require("./foo"); +export class Foo extends internal.Foo_Internal {} + +//// [foo.d.ts] +export class Foo_Internal {} + +//// [start.ts] +import foo = require("foo"); +import foofoo = require("foo/foo"); +new foo.Foo(); +new foofoo.Foo_Internal(); + + +//// [start.js] +"use strict"; +var foo = require("foo"); +var foofoo = require("foo/foo"); +new foo.Foo(); +new foofoo.Foo_Internal(); diff --git a/tests/baselines/reference/nodeResolution12.symbols b/tests/baselines/reference/nodeResolution12.symbols new file mode 100644 index 0000000000000..5b2edae2a09e5 --- /dev/null +++ b/tests/baselines/reference/nodeResolution12.symbols @@ -0,0 +1,31 @@ +=== tests/cases/compiler/start.ts === +import foo = require("foo"); +>foo : Symbol(foo, Decl(start.ts, 0, 0)) + +import foofoo = require("foo/foo"); +>foofoo : Symbol(foofoo, Decl(start.ts, 0, 28)) + +new foo.Foo(); +>foo.Foo : Symbol(foo.Foo, Decl(index.d.ts, 0, 35)) +>foo : Symbol(foo, Decl(start.ts, 0, 0)) +>Foo : Symbol(foo.Foo, Decl(index.d.ts, 0, 35)) + +new foofoo.Foo_Internal(); +>foofoo.Foo_Internal : Symbol(foofoo.Foo_Internal, Decl(foo.d.ts, 0, 0)) +>foofoo : Symbol(foofoo, Decl(start.ts, 0, 28)) +>Foo_Internal : Symbol(foofoo.Foo_Internal, Decl(foo.d.ts, 0, 0)) + +=== tests/cases/compiler/node_modules/foo/index.d.ts === +import internal = require("./foo"); +>internal : Symbol(internal, Decl(index.d.ts, 0, 0)) + +export class Foo extends internal.Foo_Internal {} +>Foo : Symbol(Foo, Decl(index.d.ts, 0, 35)) +>internal.Foo_Internal : Symbol(internal.Foo_Internal, Decl(foo.d.ts, 0, 0)) +>internal : Symbol(internal, Decl(index.d.ts, 0, 0)) +>Foo_Internal : Symbol(internal.Foo_Internal, Decl(foo.d.ts, 0, 0)) + +=== tests/cases/compiler/node_modules/foo/foo.d.ts === +export class Foo_Internal {} +>Foo_Internal : Symbol(Foo_Internal, Decl(foo.d.ts, 0, 0)) + diff --git a/tests/baselines/reference/nodeResolution12.types b/tests/baselines/reference/nodeResolution12.types new file mode 100644 index 0000000000000..b98bfc4d6645a --- /dev/null +++ b/tests/baselines/reference/nodeResolution12.types @@ -0,0 +1,33 @@ +=== tests/cases/compiler/start.ts === +import foo = require("foo"); +>foo : typeof foo + +import foofoo = require("foo/foo"); +>foofoo : typeof foofoo + +new foo.Foo(); +>new foo.Foo() : foo.Foo +>foo.Foo : typeof foo.Foo +>foo : typeof foo +>Foo : typeof foo.Foo + +new foofoo.Foo_Internal(); +>new foofoo.Foo_Internal() : foofoo.Foo_Internal +>foofoo.Foo_Internal : typeof foofoo.Foo_Internal +>foofoo : typeof foofoo +>Foo_Internal : typeof foofoo.Foo_Internal + +=== tests/cases/compiler/node_modules/foo/index.d.ts === +import internal = require("./foo"); +>internal : typeof internal + +export class Foo extends internal.Foo_Internal {} +>Foo : Foo +>internal.Foo_Internal : internal.Foo_Internal +>internal : typeof internal +>Foo_Internal : typeof internal.Foo_Internal + +=== tests/cases/compiler/node_modules/foo/foo.d.ts === +export class Foo_Internal {} +>Foo_Internal : Foo_Internal + diff --git a/tests/baselines/reference/nodeResolution13.errors.txt b/tests/baselines/reference/nodeResolution13.errors.txt new file mode 100644 index 0000000000000..8d175d3349395 --- /dev/null +++ b/tests/baselines/reference/nodeResolution13.errors.txt @@ -0,0 +1,26 @@ +tests/cases/compiler/node_modules/bar/index.d.ts(1,1): error TS6064: File 'tests/cases/compiler/node_modules/baz/include.d.ts' was referenced by a package 'tests/cases/compiler/bar' but is already included by package 'tests/cases/compiler/foo'. +tests/cases/compiler/node_modules/bar/index.d.ts(2,26): error TS2304: Cannot find name 'BazShim'. + + +==== tests/cases/compiler/start.ts (0 errors) ==== + import foo = require("foo"); + import bar = require("bar"); + + new foo.Foo(); + new bar.Bar(); + +==== tests/cases/compiler/node_modules/foo/index.d.ts (0 errors) ==== + /// + export class Foo extends BazShim {} + +==== tests/cases/compiler/node_modules/bar/index.d.ts (2 errors) ==== + /// + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS6064: File 'include.d.ts' was referenced by a package 'tests/cases/compiler/bar' but is already included by package 'tests/cases/compiler/foo'. + export class Bar extends BazShim {} + ~~~~~~~ +!!! error TS2304: Cannot find name 'BazShim'. + +==== tests/cases/compiler/node_modules/baz/include.d.ts (0 errors) ==== + declare class BazShim {} + \ No newline at end of file diff --git a/tests/baselines/reference/nodeResolution13.js b/tests/baselines/reference/nodeResolution13.js new file mode 100644 index 0000000000000..83bb9cf95be73 --- /dev/null +++ b/tests/baselines/reference/nodeResolution13.js @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/nodeResolution13.ts] //// + +//// [index.d.ts] +/// +export class Foo extends BazShim {} + +//// [index.d.ts] +/// +export class Bar extends BazShim {} + +//// [include.d.ts] +declare class BazShim {} + +//// [start.ts] +import foo = require("foo"); +import bar = require("bar"); + +new foo.Foo(); +new bar.Bar(); + + +//// [start.js] +"use strict"; +var foo = require("foo"); +var bar = require("bar"); +new foo.Foo(); +new bar.Bar(); diff --git a/tests/baselines/reference/nodeResolution5.errors.txt b/tests/baselines/reference/nodeResolution5.errors.txt deleted file mode 100644 index c36cce45b6d0b..0000000000000 --- a/tests/baselines/reference/nodeResolution5.errors.txt +++ /dev/null @@ -1,14 +0,0 @@ -tests/cases/compiler/b.ts(1,20): error TS2656: Exported external package typings file 'tests/cases/compiler/node_modules/a.d.ts' is not a module. Please contact the package author to update the package definition. - - -==== tests/cases/compiler/b.ts (1 errors) ==== - import y = require("a"); - ~~~ -!!! error TS2656: Exported external package typings file 'a.d.ts' is not a module. Please contact the package author to update the package definition. - -==== tests/cases/compiler/node_modules/a.d.ts (0 errors) ==== - - declare module "a" { - var x: number; - } - \ No newline at end of file diff --git a/tests/baselines/reference/nodeResolution5.symbols b/tests/baselines/reference/nodeResolution5.symbols new file mode 100644 index 0000000000000..be4aa2be0e966 --- /dev/null +++ b/tests/baselines/reference/nodeResolution5.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/b.ts === +import y = require("a"); +>y : Symbol(y, Decl(b.ts, 0, 0)) + +=== tests/cases/compiler/node_modules/a.d.ts === + +declare module "a" { + var x: number; +>x : Symbol(x, Decl(a.d.ts, 2, 7)) +} + diff --git a/tests/baselines/reference/nodeResolution5.types b/tests/baselines/reference/nodeResolution5.types new file mode 100644 index 0000000000000..14f5bd24f5d37 --- /dev/null +++ b/tests/baselines/reference/nodeResolution5.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/b.ts === +import y = require("a"); +>y : typeof y + +=== tests/cases/compiler/node_modules/a.d.ts === + +declare module "a" { + var x: number; +>x : number +} + diff --git a/tests/baselines/reference/nodeResolution6.errors.txt b/tests/baselines/reference/nodeResolution6.errors.txt index 6bab6e34389d5..219dfa5648de7 100644 --- a/tests/baselines/reference/nodeResolution6.errors.txt +++ b/tests/baselines/reference/nodeResolution6.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/node_modules/a.d.ts(1,1): error TS2654: Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition. +tests/cases/compiler/node_modules/a.d.ts(1,1): error TS2654: Exported external package typings file cannot contain script file tripleslash references. Please contact the package author to update the package definition. ==== tests/cases/compiler/b.ts (0 errors) ==== @@ -11,7 +11,7 @@ tests/cases/compiler/node_modules/a.d.ts(1,1): error TS2654: Exported external p ==== tests/cases/compiler/node_modules/a.d.ts (1 errors) ==== /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2654: Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition. +!!! error TS2654: Exported external package typings file cannot contain script file tripleslash references. Please contact the package author to update the package definition. export declare var y; \ No newline at end of file diff --git a/tests/baselines/reference/nodeResolution7.errors.txt b/tests/baselines/reference/nodeResolution7.errors.txt deleted file mode 100644 index f9e8ef7ac0fc6..0000000000000 --- a/tests/baselines/reference/nodeResolution7.errors.txt +++ /dev/null @@ -1,14 +0,0 @@ -tests/cases/compiler/b.ts(1,20): error TS2656: Exported external package typings file 'tests/cases/compiler/node_modules/a/index.d.ts' is not a module. Please contact the package author to update the package definition. - - -==== tests/cases/compiler/b.ts (1 errors) ==== - import y = require("a"); - ~~~ -!!! error TS2656: Exported external package typings file 'index.d.ts' is not a module. Please contact the package author to update the package definition. - -==== tests/cases/compiler/node_modules/a/index.d.ts (0 errors) ==== - - declare module "a" { - var x: number; - } - \ No newline at end of file diff --git a/tests/baselines/reference/nodeResolution7.symbols b/tests/baselines/reference/nodeResolution7.symbols new file mode 100644 index 0000000000000..ea8d636b61b11 --- /dev/null +++ b/tests/baselines/reference/nodeResolution7.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/b.ts === +import y = require("a"); +>y : Symbol(y, Decl(b.ts, 0, 0)) + +=== tests/cases/compiler/node_modules/a/index.d.ts === + +declare module "a" { + var x: number; +>x : Symbol(x, Decl(index.d.ts, 2, 7)) +} + diff --git a/tests/baselines/reference/nodeResolution7.types b/tests/baselines/reference/nodeResolution7.types new file mode 100644 index 0000000000000..1cb14150bdee5 --- /dev/null +++ b/tests/baselines/reference/nodeResolution7.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/b.ts === +import y = require("a"); +>y : typeof y + +=== tests/cases/compiler/node_modules/a/index.d.ts === + +declare module "a" { + var x: number; +>x : number +} + diff --git a/tests/baselines/reference/nodeResolution8.errors.txt b/tests/baselines/reference/nodeResolution8.errors.txt index 3f14a4313c8cd..212938022ff4f 100644 --- a/tests/baselines/reference/nodeResolution8.errors.txt +++ b/tests/baselines/reference/nodeResolution8.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/node_modules/a/index.d.ts(1,1): error TS2654: Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition. +tests/cases/compiler/node_modules/a/index.d.ts(1,1): error TS2654: Exported external package typings file cannot contain script file tripleslash references. Please contact the package author to update the package definition. ==== tests/cases/compiler/b.ts (0 errors) ==== @@ -10,7 +10,7 @@ tests/cases/compiler/node_modules/a/index.d.ts(1,1): error TS2654: Exported exte ==== tests/cases/compiler/node_modules/a/index.d.ts (1 errors) ==== /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2654: Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition. +!!! error TS2654: Exported external package typings file cannot contain script file tripleslash references. Please contact the package author to update the package definition. export declare var y; \ No newline at end of file diff --git a/tests/baselines/reference/nodeResolution9.errors.txt b/tests/baselines/reference/nodeResolution9.errors.txt new file mode 100644 index 0000000000000..fb63e965f2ce9 --- /dev/null +++ b/tests/baselines/reference/nodeResolution9.errors.txt @@ -0,0 +1,19 @@ +tests/cases/compiler/b.ts(2,20): error TS2307: Cannot find module 'internal'. + + +==== tests/cases/compiler/b.ts (1 errors) ==== + import y = require("a"); + import z = require("internal"); // should error + ~~~~~~~~~~ +!!! error TS2307: Cannot find module 'internal'. +==== tests/cases/compiler/node_modules/a/ref.d.ts (0 errors) ==== + + declare module "internal" { + export var foo: void; + } + +==== tests/cases/compiler/node_modules/a/index.d.ts (0 errors) ==== + /// + export * from "internal"; + + \ No newline at end of file diff --git a/tests/baselines/reference/nodeResolution9.js b/tests/baselines/reference/nodeResolution9.js new file mode 100644 index 0000000000000..29e0be3125a04 --- /dev/null +++ b/tests/baselines/reference/nodeResolution9.js @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/nodeResolution9.ts] //// + +//// [ref.d.ts] + +declare module "internal" { + export var foo: void; +} + +//// [index.d.ts] +/// +export * from "internal"; + + +//// [b.ts] +import y = require("a"); +import z = require("internal"); // should error + +//// [b.js] +"use strict"; diff --git a/tests/cases/compiler/nodeResolution10.ts b/tests/cases/compiler/nodeResolution10.ts new file mode 100644 index 0000000000000..6d568243c56f0 --- /dev/null +++ b/tests/cases/compiler/nodeResolution10.ts @@ -0,0 +1,33 @@ +// @module: commonjs +// @moduleResolution: node + +// @filename: node_modules/a/ref.d.ts +interface Foo { + staticMember: string; +} + +declare module "internal" { + export var foo: number; +} + +// @filename: node_modules/a/index.d.ts +/// +export var dummy: Foo; +export var dummyMember: typeof dummy.staticMember; +export var dummyMember2: typeof dummy.otherMember; // should error +export * from "internal"; + +// @filename: b.ts +import y = require("a"); + +interface Foo { + otherMember: number; +} + +let foo: number = y.foo; +let bigFoo = y.dummy; +let n = bigFoo.otherMember; // should error + +let foo2: Foo; +let t: number = foo2.otherMember; +let e: string = foo2.staticMember; // should error diff --git a/tests/cases/compiler/nodeResolution11.ts b/tests/cases/compiler/nodeResolution11.ts new file mode 100644 index 0000000000000..7dfa60d667fd2 --- /dev/null +++ b/tests/cases/compiler/nodeResolution11.ts @@ -0,0 +1,35 @@ +// @module: commonjs +// @moduleResolution: node + +// @filename: node_modules/a/ref.d.ts +interface Foo { + staticMember: string; +} + +declare module "internal" { + export var foo: number; +} + +// @filename: node_modules/a/index.d.ts +/// +export var dummy: Foo; +export var dummyMember: typeof dummy.staticMember; +export var dummyMember2: typeof dummy.otherMember; // global foo merged in, should be here +export * from "internal"; + +// @filename: ref.d.ts +interface Foo { + otherMember: number; +} + +// @filename: b.ts +/// +import y = require("a"); + +let foo: number = y.foo; +let bigFoo = y.dummy; +let n = bigFoo.otherMember; // global foo merged into package Foo, should be here + +let foo2: Foo; +let t: number = foo2.otherMember; +let e: string = foo2.staticMember; // should error, is global Foo diff --git a/tests/cases/compiler/nodeResolution12.ts b/tests/cases/compiler/nodeResolution12.ts new file mode 100644 index 0000000000000..c9013ac06d0c0 --- /dev/null +++ b/tests/cases/compiler/nodeResolution12.ts @@ -0,0 +1,14 @@ +// @module: commonjs +// @moduleResolution: node +// @filename: node_modules/foo/index.d.ts +import internal = require("./foo"); +export class Foo extends internal.Foo_Internal {} + +// @filename: node_modules/foo/foo.d.ts +export class Foo_Internal {} + +// @filename: start.ts +import foo = require("foo"); +import foofoo = require("foo/foo"); +new foo.Foo(); +new foofoo.Foo_Internal(); diff --git a/tests/cases/compiler/nodeResolution13.ts b/tests/cases/compiler/nodeResolution13.ts new file mode 100644 index 0000000000000..8d3cd77ee0ef5 --- /dev/null +++ b/tests/cases/compiler/nodeResolution13.ts @@ -0,0 +1,19 @@ +// @module: commonjs +// @moduleResolution: node +// @filename: node_modules/foo/index.d.ts +/// +export class Foo extends BazShim {} + +// @filename: node_modules/bar/index.d.ts +/// +export class Bar extends BazShim {} + +// @filename: node_modules/baz/include.d.ts +declare class BazShim {} + +// @filename: start.ts +import foo = require("foo"); +import bar = require("bar"); + +new foo.Foo(); +new bar.Bar(); diff --git a/tests/cases/compiler/nodeResolution9.ts b/tests/cases/compiler/nodeResolution9.ts new file mode 100644 index 0000000000000..c4ba5617d99bf --- /dev/null +++ b/tests/cases/compiler/nodeResolution9.ts @@ -0,0 +1,16 @@ +// @module: commonjs +// @moduleResolution: node + +// @filename: node_modules/a/ref.d.ts +declare module "internal" { + export var foo: void; +} + +// @filename: node_modules/a/index.d.ts +/// +export * from "internal"; + + +// @filename: b.ts +import y = require("a"); +import z = require("internal"); // should error \ No newline at end of file diff --git a/tests/cases/unittests/moduleResolution.ts b/tests/cases/unittests/moduleResolution.ts index c4c17ebb223eb..dd301345286ab 100644 --- a/tests/cases/unittests/moduleResolution.ts +++ b/tests/cases/unittests/moduleResolution.ts @@ -55,7 +55,7 @@ module ts { let moduleFile = { name: moduleFileNameNoExt + ext } let resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(containingFile, moduleFile)); assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name); - assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false); + assert.equal(resolution.resolvedModule.packageRoot, undefined); let failedLookupLocations: string[] = []; let dir = getDirectoryPath(containingFileName); @@ -94,8 +94,8 @@ module ts { let moduleFile = { name: moduleFileName }; let resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(containingFile, packageJson, moduleFile)); assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name); - assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false); - // expect three failed lookup location - attempt to load module as file with all supported extensions + assert.equal(resolution.resolvedModule.packageRoot, packageJsonFileName); + // expect five failed lookup location - attempt to load module as file with all supported extensions assert.equal(resolution.failedLookupLocations.length, supportedTypeScriptExtensions.length); } @@ -112,7 +112,7 @@ module ts { let indexFile = { name: "/a/b/foo/index.d.ts" }; let resolution = nodeModuleNameResolver("./foo", containingFile.name, {}, createModuleResolutionHost(containingFile, packageJson, indexFile)); assert.equal(resolution.resolvedModule.resolvedFileName, indexFile.name); - assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false); + assert.equal(resolution.resolvedModule.packageRoot, undefined); assert.deepEqual(resolution.failedLookupLocations, [ "/a/b/foo.ts", "/a/b/foo.tsx", @@ -152,7 +152,7 @@ module ts { let moduleFile = { name: "/a/b/node_modules/foo.d.ts" }; let resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(containingFile, moduleFile)); assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name); - assert.equal(resolution.resolvedModule.isExternalLibraryImport, true); + assert.equal(resolution.resolvedModule.packageRoot, "/a/b/node_modules/foo.d.ts"); }); it("load module as directory", () => { @@ -160,7 +160,7 @@ module ts { let moduleFile = { name: "/a/node_modules/foo/index.d.ts" }; let resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(containingFile, moduleFile)); assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name); - assert.equal(resolution.resolvedModule.isExternalLibraryImport, true); + assert.equal(resolution.resolvedModule.packageRoot, "/a/node_modules/foo/index.d.ts"); assert.deepEqual(resolution.failedLookupLocations, [ "/a/node_modules/b/c/node_modules/d/node_modules/foo.ts", "/a/node_modules/b/c/node_modules/d/node_modules/foo.tsx", diff --git a/tests/cases/unittests/reuseProgramStructure.ts b/tests/cases/unittests/reuseProgramStructure.ts index 5f313eeae2b32..f9c9e0bf952c8 100644 --- a/tests/cases/unittests/reuseProgramStructure.ts +++ b/tests/cases/unittests/reuseProgramStructure.ts @@ -162,15 +162,15 @@ module ts { function checkResolvedModulesCache(program: Program, fileName: string, expectedContent: Map): void { let file = program.getSourceFile(fileName); - assert.isTrue(file !== undefined, `cannot find file ${fileName}`); + assert.notEqual(file, undefined, `cannot find file ${fileName}`); if (expectedContent === undefined) { - assert.isTrue(file.resolvedModules === undefined, "expected resolvedModules to be undefined"); + assert.equal(file.resolvedModules, undefined, "expected resolvedModules to be undefined"); } else { assert.isTrue(file.resolvedModules !== undefined, "expected resolvedModuled to be set"); let actualCacheSize = getSizeOfMap(file.resolvedModules); let expectedSize = getSizeOfMap(expectedContent); - assert.isTrue(actualCacheSize === expectedSize, `expected actual size: ${actualCacheSize} to be equal to ${expectedSize}`); + assert.equal(actualCacheSize, expectedSize, `expected actual size: ${actualCacheSize} to be equal to ${expectedSize}`); for (let id in expectedContent) { if (hasProperty(expectedContent, id)) { @@ -178,12 +178,12 @@ module ts { if (expectedContent[id]) { const expected = expectedContent[id]; const actual = file.resolvedModules[id]; - assert.isTrue(actual !== undefined); - assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`); - assert.isTrue(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'shouldBeProperExternalModule': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`); + assert.notEqual(actual, undefined); + assert.equal(expected.resolvedFileName, actual.resolvedFileName); + assert.equal(expected.packageRoot, actual.packageRoot); } else { - assert.isTrue(file.resolvedModules[id] === undefined); + assert.equal(file.resolvedModules[id], undefined); } } }