;
+
+// @filename: Error5.tsx
+let x5 =
+
diff --git a/tests/cases/conformance/jsx/tsxPreserveEmit2.tsx b/tests/cases/conformance/jsx/tsxPreserveEmit2.tsx
new file mode 100644
index 00000000000..978c96a2019
--- /dev/null
+++ b/tests/cases/conformance/jsx/tsxPreserveEmit2.tsx
@@ -0,0 +1,8 @@
+//@module: amd
+//@jsx: preserve
+//@target: ES5
+
+//@Filename: test.tsx
+
+var Route: any;
+var routes1 = ;
diff --git a/tests/cases/conformance/jsx/tsxPreserveEmit3.tsx b/tests/cases/conformance/jsx/tsxPreserveEmit3.tsx
new file mode 100644
index 00000000000..d7565cacbe2
--- /dev/null
+++ b/tests/cases/conformance/jsx/tsxPreserveEmit3.tsx
@@ -0,0 +1,17 @@
+//@jsx: preserve
+//@module: amd
+
+//@filename: file.tsx
+declare module JSX {
+ interface Element { }
+ interface IntrinsicElements {
+ [s: string]: any;
+ }
+}
+
+//@filename: test.d.ts
+export var React;
+
+//@filename: react-consumer.tsx
+// This import should be elided
+import {React} from "./test";
diff --git a/tests/cases/conformance/jsx/tsxReactEmitEntities.tsx b/tests/cases/conformance/jsx/tsxReactEmitEntities.tsx
index 4b7dc5780f8..4726008d6be 100644
--- a/tests/cases/conformance/jsx/tsxReactEmitEntities.tsx
+++ b/tests/cases/conformance/jsx/tsxReactEmitEntities.tsx
@@ -9,3 +9,4 @@ declare module JSX {
declare var React: any;
Dot goes here: · ¬AnEntity;
;
+Be careful of "-ed strings!
;
diff --git a/tests/cases/conformance/types/contextualTypes/commaOperator/contextuallyTypeCommaOperator01.ts b/tests/cases/conformance/types/contextualTypes/commaOperator/contextuallyTypeCommaOperator01.ts
new file mode 100644
index 00000000000..167369a020b
--- /dev/null
+++ b/tests/cases/conformance/types/contextualTypes/commaOperator/contextuallyTypeCommaOperator01.ts
@@ -0,0 +1,5 @@
+// @noImplicitAny: true
+
+let x: (a: string) => string;
+
+x = (100, a => a);
\ No newline at end of file
diff --git a/tests/cases/conformance/types/contextualTypes/commaOperator/contextuallyTypeCommaOperator02.ts b/tests/cases/conformance/types/contextualTypes/commaOperator/contextuallyTypeCommaOperator02.ts
new file mode 100644
index 00000000000..11e743b583e
--- /dev/null
+++ b/tests/cases/conformance/types/contextualTypes/commaOperator/contextuallyTypeCommaOperator02.ts
@@ -0,0 +1,8 @@
+// @noImplicitAny: true
+
+let x: (a: string) => string;
+
+x = (100, a => {
+ const b: number = a;
+ return b;
+});
\ No newline at end of file
diff --git a/tests/cases/conformance/types/contextualTypes/commaOperator/contextuallyTypeCommaOperator03.ts b/tests/cases/conformance/types/contextualTypes/commaOperator/contextuallyTypeCommaOperator03.ts
new file mode 100644
index 00000000000..321eb99d153
--- /dev/null
+++ b/tests/cases/conformance/types/contextualTypes/commaOperator/contextuallyTypeCommaOperator03.ts
@@ -0,0 +1,5 @@
+// @noImplicitAny: true
+
+let x: (a: string) => string;
+
+x = (a => a, b => b);
\ No newline at end of file
diff --git a/tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx b/tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx
new file mode 100644
index 00000000000..ce6f4b7ac2f
--- /dev/null
+++ b/tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx
@@ -0,0 +1,16 @@
+// @jsx: preserve
+// @declaration: true
+
+namespace JSX {
+ interface IntrinsicElements {
+ span: {};
+ }
+}
+
+const FooComponent = (props: { foo: "A" | "B" | "C" }) => {props.foo};
+
+;
+;
+
+;
+;
\ No newline at end of file
diff --git a/tests/cases/conformance/types/contextualTypes/logicalAnd/contextuallyTypeLogicalAnd01.ts b/tests/cases/conformance/types/contextualTypes/logicalAnd/contextuallyTypeLogicalAnd01.ts
new file mode 100644
index 00000000000..30e46429fa1
--- /dev/null
+++ b/tests/cases/conformance/types/contextualTypes/logicalAnd/contextuallyTypeLogicalAnd01.ts
@@ -0,0 +1,6 @@
+// @noImplicitAny: true
+
+let x: (a: string) => string;
+let y = true;
+
+x = y && (a => a);
\ No newline at end of file
diff --git a/tests/cases/conformance/types/contextualTypes/logicalAnd/contextuallyTypeLogicalAnd02.ts b/tests/cases/conformance/types/contextualTypes/logicalAnd/contextuallyTypeLogicalAnd02.ts
new file mode 100644
index 00000000000..26e58ae49ec
--- /dev/null
+++ b/tests/cases/conformance/types/contextualTypes/logicalAnd/contextuallyTypeLogicalAnd02.ts
@@ -0,0 +1,9 @@
+// @noImplicitAny: true
+
+let x: (a: string) => string;
+let y = true;
+
+x = y && (a => {
+ const b: number = a;
+ return b;
+});
\ No newline at end of file
diff --git a/tests/cases/conformance/types/contextualTypes/logicalAnd/contextuallyTypeLogicalAnd03.ts b/tests/cases/conformance/types/contextualTypes/logicalAnd/contextuallyTypeLogicalAnd03.ts
new file mode 100644
index 00000000000..1fba96c048a
--- /dev/null
+++ b/tests/cases/conformance/types/contextualTypes/logicalAnd/contextuallyTypeLogicalAnd03.ts
@@ -0,0 +1,6 @@
+// @noImplicitAny: true
+
+let x: (a: string) => string;
+let y = true;
+
+x = (a => a) && (b => b);
\ No newline at end of file
diff --git a/tests/cases/fourslash/formatDocumentWithTrivia.ts b/tests/cases/fourslash/formatDocumentWithTrivia.ts
new file mode 100644
index 00000000000..d51677be81d
--- /dev/null
+++ b/tests/cases/fourslash/formatDocumentWithTrivia.ts
@@ -0,0 +1,51 @@
+///
+
+////
+////// whitespace below
+////
+////// whitespace above
+////
+////let x;
+////
+////// abc
+////
+////let y;
+////
+////// whitespace above again
+////
+////while (true) {
+//// while (true) {
+//// }
+////
+//// // whitespace above
+////}
+////
+////// whitespace above again
+////
+////
+
+format.document();
+
+verify.currentFileContentIs(`
+// whitespace below
+
+// whitespace above
+
+let x;
+
+// abc
+
+let y;
+
+// whitespace above again
+
+while (true) {
+ while (true) {
+ }
+
+ // whitespace above
+}
+
+// whitespace above again
+
+`);
diff --git a/tests/cases/fourslash/formatSelectionWithTrivia2.ts b/tests/cases/fourslash/formatSelectionWithTrivia2.ts
new file mode 100644
index 00000000000..06b43009a22
--- /dev/null
+++ b/tests/cases/fourslash/formatSelectionWithTrivia2.ts
@@ -0,0 +1,10 @@
+///
+
+/////*begin*/;
+////
+/////*end*/
+////
+
+format.selection('begin', 'end');
+
+verify.currentFileContentIs(";\n\n\n ");
diff --git a/tests/cases/fourslash/formatTemplateLiteral.ts b/tests/cases/fourslash/formatTemplateLiteral.ts
index 68f2c8c9469..a10f8dba8f2 100644
--- a/tests/cases/fourslash/formatTemplateLiteral.ts
+++ b/tests/cases/fourslash/formatTemplateLiteral.ts
@@ -32,9 +32,9 @@ verify.currentLineContentIs("let w = `bar${3}`;");
goTo.marker("5");
verify.currentLineContentIs(" `template`;");
goTo.marker("6");
-verify.currentLineContentIs("String.raw `foo`;");
+verify.currentLineContentIs("String.raw`foo`;");
goTo.marker("7");
-verify.currentLineContentIs("String.raw `bar${3}`;");
+verify.currentLineContentIs("String.raw`bar${3}`;");
goTo.marker("spaceInside");
verify.currentLineContentIs('`Write ${JSON.stringify("")} and ${(765)} and ${346}`;');
\ No newline at end of file
diff --git a/tests/cases/fourslash/formattingInExpressionsInTsx.ts b/tests/cases/fourslash/formattingInExpressionsInTsx.ts
new file mode 100644
index 00000000000..f02a5a5b291
--- /dev/null
+++ b/tests/cases/fourslash/formattingInExpressionsInTsx.ts
@@ -0,0 +1,14 @@
+///
+
+// @Filename: test.tsx
+////import * as React from "react";
+////
+////
+
+goTo.marker("1");
+edit.insert(";");
+verify.currentLineContentIs(" return true;");
\ No newline at end of file
diff --git a/tests/cases/fourslash/formattingJsxElements.ts b/tests/cases/fourslash/formattingJsxElements.ts
index fd4ccc504a4..fbe4bb5d29e 100644
--- a/tests/cases/fourslash/formattingJsxElements.ts
+++ b/tests/cases/fourslash/formattingJsxElements.ts
@@ -9,7 +9,7 @@
////
//// )
////}
-////
+////
////function foo1() {
//// return (
////
@@ -45,8 +45,26 @@
//// class3= {/*5*/
//// }/>/*6*/
//// )
+////}
+////
+////(function () {
+//// return
/*danglingBracketAutoformat*/
+////
/*closingTagAutoformat*/
+////})
+////
+////let h5 =
+/////*childJsxElementAutoformat*/
+/////*childJsxElementIndent*/
+/////*grandchildJsxElementAutoformat*/
+/////*containedClosingTagAutoformat*/
+////
format.document();
goTo.marker("autoformat");
@@ -83,3 +101,28 @@ goTo.marker("5");
verify.currentLineContentIs(' class3= {');
goTo.marker("6");
verify.currentLineContentIs(' }/>');
+
+
+goTo.marker("attrAutoformat");
+verify.currentLineContentIs(' className=""');
+goTo.marker("attrIndent");
+verify.indentationIs(8);
+goTo.marker("expressionAutoformat");
+verify.currentLineContentIs(' "abc" + "cde"');
+goTo.marker("expressionIndent");
+verify.indentationIs(12);
+
+goTo.marker("danglingBracketAutoformat")
+// TODO: verify.currentLineContentIs(" >");
+verify.currentLineContentIs(" >");
+goTo.marker("closingTagAutoformat");
+verify.currentLineContentIs("
");
+
+goTo.marker("childJsxElementAutoformat");
+verify.currentLineContentIs("
");
+goTo.marker("childJsxElementIndent");
+verify.indentationIs(8);
+goTo.marker("grandchildJsxElementAutoformat");
+verify.currentLineContentIs(" ");
+goTo.marker("containedClosingTagAutoformat");
+verify.currentLineContentIs(" ");
\ No newline at end of file
diff --git a/tests/cases/fourslash/formattingOptionsChange.ts b/tests/cases/fourslash/formattingOptionsChange.ts
index cdd8f61a215..f266a8e96c1 100644
--- a/tests/cases/fourslash/formattingOptionsChange.ts
+++ b/tests/cases/fourslash/formattingOptionsChange.ts
@@ -1,24 +1,26 @@
///
-/////*InsertSpaceAfterCommaDelimiter*/[1,2, 3];
+/////*InsertSpaceAfterCommaDelimiter*/[1,2, 3];[ 72 , ];
/////*InsertSpaceAfterSemicolonInForStatements*/for (i = 0;i; i++);
/////*InsertSpaceBeforeAndAfterBinaryOperators*/1+2- 3
/////*InsertSpaceAfterKeywordsInControlFlowStatements*/if (true) { }
/////*InsertSpaceAfterFunctionKeywordForAnonymousFunctions*/(function () { })
/////*InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis*/(1 )
-/////*InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets*/[1 ]; [ ]; []; [,]
+/////*InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets*/[1 ]; [ ]; []; [,];
+/////*InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces*/`${1}`;`${ 1 }`
/////*PlaceOpenBraceOnNewLineForFunctions*/class foo {
////}
/////*PlaceOpenBraceOnNewLineForControlBlocks*/if (true) {
////}
-runTest("InsertSpaceAfterCommaDelimiter", "[1, 2, 3];", "[1,2,3];");
+runTest("InsertSpaceAfterCommaDelimiter", "[1, 2, 3];[72,];", "[1,2,3];[72,];");
runTest("InsertSpaceAfterSemicolonInForStatements", "for (i = 0; i; i++);", "for (i = 0;i;i++);");
runTest("InsertSpaceBeforeAndAfterBinaryOperators", "1 + 2 - 3", "1+2-3");
runTest("InsertSpaceAfterKeywordsInControlFlowStatements", "if (true) { }", "if(true) { }");
runTest("InsertSpaceAfterFunctionKeywordForAnonymousFunctions", "(function () { })", "(function() { })");
runTest("InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis", " ( 1 )", " (1)");
-runTest("InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets", "[ 1 ];[];[];[ , ]", "[1];[];[];[, ]");
+runTest("InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets", "[ 1 ];[];[];[ , ];", "[1];[];[];[,];");
+runTest("InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces", "`${ 1 }`; `${ 1 }`", "`${1}`; `${1}`");
runTest("PlaceOpenBraceOnNewLineForFunctions", "class foo", "class foo {");
runTest("PlaceOpenBraceOnNewLineForControlBlocks", "if ( true )", "if ( true ) {");
diff --git a/tests/cases/fourslash/formattingTemplates.ts b/tests/cases/fourslash/formattingTemplates.ts
index c7decd10316..c759376335d 100644
--- a/tests/cases/fourslash/formattingTemplates.ts
+++ b/tests/cases/fourslash/formattingTemplates.ts
@@ -5,8 +5,8 @@
goTo.marker("1");
edit.insert(";");
-verify.currentLineContentIs("String.call `${123}`;");
+verify.currentLineContentIs("String.call`${123}`;");
goTo.marker("2");
edit.insert(";");
-verify.currentLineContentIs("String.call `${123} ${456}`;");
\ No newline at end of file
+verify.currentLineContentIs("String.call`${123} ${456}`;");
\ No newline at end of file
diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts
index dd443e942cf..0e83189dd8e 100644
--- a/tests/cases/fourslash/fourslash.ts
+++ b/tests/cases/fourslash/fourslash.ts
@@ -81,6 +81,7 @@ declare namespace FourSlashInterface {
InsertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean;
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean;
InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean;
+ InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean;
PlaceOpenBraceOnNewLineForFunctions: boolean;
PlaceOpenBraceOnNewLineForControlBlocks: boolean;
[s: string]: boolean | number | string;
diff --git a/tests/cases/unittests/moduleResolution.ts b/tests/cases/unittests/moduleResolution.ts
index 5b924650401..81d7c5f8b2e 100644
--- a/tests/cases/unittests/moduleResolution.ts
+++ b/tests/cases/unittests/moduleResolution.ts
@@ -26,15 +26,36 @@ module ts {
content?: string
}
- function createModuleResolutionHost(...files: File[]): ModuleResolutionHost {
+ function createModuleResolutionHost(hasDirectoryExists: boolean, ...files: File[]): ModuleResolutionHost {
let map = arrayToMap(files, f => f.name);
- return { fileExists, readFile };
-
- function fileExists(path: string): boolean {
- return hasProperty(map, path);
+ if (hasDirectoryExists) {
+ const directories: Map
= {};
+ for (const f of files) {
+ let name = getDirectoryPath(f.name);
+ while (true) {
+ directories[name] = name;
+ let baseName = getDirectoryPath(name);
+ if (baseName === name) {
+ break;
+ }
+ name = baseName;
+ }
+ }
+ return {
+ readFile,
+ directoryExists: path => {
+ return hasProperty(directories, path);
+ },
+ fileExists: path => {
+ assert.isTrue(hasProperty(directories, getDirectoryPath(path)), "'fileExists' request in non-existing directory");
+ return hasProperty(map, path);
+ }
+ }
+ }
+ else {
+ return { readFile, fileExists: path => hasProperty(map, path), };
}
-
function readFile(path: string): string {
return hasProperty(map, path) ? map[path].content : undefined;
}
@@ -51,9 +72,14 @@ module ts {
function testLoadAsFile(containingFileName: string, moduleFileNameNoExt: string, moduleName: string): void {
for (let ext of supportedTypeScriptExtensions) {
+ test(ext, /*hasDirectoryExists*/ false);
+ test(ext, /*hasDirectoryExists*/ true);
+ }
+
+ function test(ext: string, hasDirectoryExists: boolean) {
let containingFile = { name: containingFileName }
let moduleFile = { name: moduleFileNameNoExt + ext }
- let resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(containingFile, moduleFile));
+ let resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
@@ -69,6 +95,7 @@ module ts {
}
assert.deepEqual(resolution.failedLookupLocations, failedLookupLocations);
+
}
}
@@ -89,14 +116,19 @@ module ts {
});
function testLoadingFromPackageJson(containingFileName: string, packageJsonFileName: string, fieldRef: string, moduleFileName: string, moduleName: string): void {
- let containingFile = { name: containingFileName };
- let packageJson = { name: packageJsonFileName, content: JSON.stringify({ "typings": fieldRef }) };
- 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.failedLookupLocations.length, supportedTypeScriptExtensions.length);
+ test(/*hasDirectoryExists*/ false);
+ test(/*hasDirectoryExists*/ true);
+
+ function test(hasDirectoryExists: boolean) {
+ let containingFile = { name: containingFileName };
+ let packageJson = { name: packageJsonFileName, content: JSON.stringify({ "typings": fieldRef }) };
+ let moduleFile = { name: moduleFileName };
+ let resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, 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.failedLookupLocations.length, supportedTypeScriptExtensions.length);
+ }
}
it("module name as directory - load from 'typings'", () => {
@@ -107,16 +139,21 @@ module ts {
});
function testTypingsIgnored(typings: any): void {
- let containingFile = { name: "/a/b.ts" };
- let packageJson = { name: "/node_modules/b/package.json", content: JSON.stringify({ "typings": typings }) };
- let moduleFile = { name: "/a/b.d.ts" };
+ test(/*hasDirectoryExists*/ false);
+ test(/*hasDirectoryExists*/ true);
- let indexPath = "/node_modules/b/index.d.ts";
- let indexFile = { name: indexPath }
+ function test(hasDirectoryExists: boolean) {
+ let containingFile = { name: "/a/b.ts" };
+ let packageJson = { name: "/node_modules/b/package.json", content: JSON.stringify({ "typings": typings }) };
+ let moduleFile = { name: "/a/b.d.ts" };
- let resolution = nodeModuleNameResolver("b", containingFile.name, {}, createModuleResolutionHost(containingFile, packageJson, moduleFile, indexFile));
+ let indexPath = "/node_modules/b/index.d.ts";
+ let indexFile = { name: indexPath }
- assert.equal(resolution.resolvedModule.resolvedFileName, indexPath);
+ let resolution = nodeModuleNameResolver("b", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile, indexFile));
+
+ assert.equal(resolution.resolvedModule.resolvedFileName, indexPath);
+ }
}
it("module name as directory - handle invalid 'typings'", () => {
@@ -128,89 +165,110 @@ module ts {
});
it("module name as directory - load index.d.ts", () => {
- let containingFile = { name: "/a/b/c.ts" };
- let packageJson = { name: "/a/b/foo/package.json", content: JSON.stringify({ main: "/c/d" }) };
- 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.deepEqual(resolution.failedLookupLocations, [
- "/a/b/foo.ts",
- "/a/b/foo.tsx",
- "/a/b/foo.d.ts",
- "/a/b/foo/index.ts",
- "/a/b/foo/index.tsx",
- ]);
+ test(/*hasDirectoryExists*/ false);
+ test(/*hasDirectoryExists*/ true);
+
+ function test(hasDirectoryExists: boolean) {
+ let containingFile = { name: "/a/b/c.ts" };
+ let packageJson = { name: "/a/b/foo/package.json", content: JSON.stringify({ main: "/c/d" }) };
+ let indexFile = { name: "/a/b/foo/index.d.ts" };
+ let resolution = nodeModuleNameResolver("./foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, indexFile));
+ assert.equal(resolution.resolvedModule.resolvedFileName, indexFile.name);
+ assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
+ assert.deepEqual(resolution.failedLookupLocations, [
+ "/a/b/foo.ts",
+ "/a/b/foo.tsx",
+ "/a/b/foo.d.ts",
+ "/a/b/foo/index.ts",
+ "/a/b/foo/index.tsx",
+ ]);
+ }
});
});
describe("Node module resolution - non-relative paths", () => {
it("load module as file - ts files not loaded", () => {
- let containingFile = { name: "/a/b/c/d/e.ts" };
- let moduleFile = { name: "/a/b/node_modules/foo.ts" };
- let resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(containingFile, moduleFile));
- assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
- assert.deepEqual(resolution.failedLookupLocations, [
- "/a/b/c/d/node_modules/foo.ts",
- "/a/b/c/d/node_modules/foo.tsx",
- "/a/b/c/d/node_modules/foo.d.ts",
- "/a/b/c/d/node_modules/foo/package.json",
- "/a/b/c/d/node_modules/foo/index.ts",
- "/a/b/c/d/node_modules/foo/index.tsx",
- "/a/b/c/d/node_modules/foo/index.d.ts",
- "/a/b/c/node_modules/foo.ts",
- "/a/b/c/node_modules/foo.tsx",
- "/a/b/c/node_modules/foo.d.ts",
- "/a/b/c/node_modules/foo/package.json",
- "/a/b/c/node_modules/foo/index.ts",
- "/a/b/c/node_modules/foo/index.tsx",
- "/a/b/c/node_modules/foo/index.d.ts",
- ])
+ test(/*hasDirectoryExists*/ false);
+ test(/*hasDirectoryExists*/ true);
+
+ function test(hasDirectoryExists: boolean) {
+ let containingFile = { name: "/a/b/c/d/e.ts" };
+ let moduleFile = { name: "/a/b/node_modules/foo.ts" };
+ let resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
+ assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
+ assert.deepEqual(resolution.failedLookupLocations, [
+ "/a/b/c/d/node_modules/foo.ts",
+ "/a/b/c/d/node_modules/foo.tsx",
+ "/a/b/c/d/node_modules/foo.d.ts",
+ "/a/b/c/d/node_modules/foo/package.json",
+ "/a/b/c/d/node_modules/foo/index.ts",
+ "/a/b/c/d/node_modules/foo/index.tsx",
+ "/a/b/c/d/node_modules/foo/index.d.ts",
+ "/a/b/c/node_modules/foo.ts",
+ "/a/b/c/node_modules/foo.tsx",
+ "/a/b/c/node_modules/foo.d.ts",
+ "/a/b/c/node_modules/foo/package.json",
+ "/a/b/c/node_modules/foo/index.ts",
+ "/a/b/c/node_modules/foo/index.tsx",
+ "/a/b/c/node_modules/foo/index.d.ts",
+ ])
+ }
});
it("load module as file", () => {
- let containingFile = { name: "/a/b/c/d/e.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);
+ test(/*hasDirectoryExists*/ false);
+ test(/*hasDirectoryExists*/ true);
+
+ function test(hasDirectoryExists: boolean) {
+ let containingFile = { name: "/a/b/c/d/e.ts" };
+ let moduleFile = { name: "/a/b/node_modules/foo.d.ts" };
+ let resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
+ assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
+ assert.equal(resolution.resolvedModule.isExternalLibraryImport, true);
+ }
});
it("load module as directory", () => {
- let containingFile = { name: "/a/node_modules/b/c/node_modules/d/e.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.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",
- "/a/node_modules/b/c/node_modules/d/node_modules/foo.d.ts",
- "/a/node_modules/b/c/node_modules/d/node_modules/foo/package.json",
- "/a/node_modules/b/c/node_modules/d/node_modules/foo/index.ts",
- "/a/node_modules/b/c/node_modules/d/node_modules/foo/index.tsx",
- "/a/node_modules/b/c/node_modules/d/node_modules/foo/index.d.ts",
- "/a/node_modules/b/c/node_modules/foo.ts",
- "/a/node_modules/b/c/node_modules/foo.tsx",
- "/a/node_modules/b/c/node_modules/foo.d.ts",
- "/a/node_modules/b/c/node_modules/foo/package.json",
- "/a/node_modules/b/c/node_modules/foo/index.ts",
- "/a/node_modules/b/c/node_modules/foo/index.tsx",
- "/a/node_modules/b/c/node_modules/foo/index.d.ts",
- "/a/node_modules/b/node_modules/foo.ts",
- "/a/node_modules/b/node_modules/foo.tsx",
- "/a/node_modules/b/node_modules/foo.d.ts",
- "/a/node_modules/b/node_modules/foo/package.json",
- "/a/node_modules/b/node_modules/foo/index.ts",
- "/a/node_modules/b/node_modules/foo/index.tsx",
- "/a/node_modules/b/node_modules/foo/index.d.ts",
- "/a/node_modules/foo.ts",
- "/a/node_modules/foo.tsx",
- "/a/node_modules/foo.d.ts",
- "/a/node_modules/foo/package.json",
- "/a/node_modules/foo/index.ts",
- "/a/node_modules/foo/index.tsx"
- ]);
+ test(/*hasDirectoryExists*/ false);
+ test(/*hasDirectoryExists*/ true);
+
+ function test(hasDirectoryExists: boolean) {
+ let containingFile = { name: "/a/node_modules/b/c/node_modules/d/e.ts" };
+ let moduleFile = { name: "/a/node_modules/foo/index.d.ts" };
+ let resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
+ assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
+ assert.equal(resolution.resolvedModule.isExternalLibraryImport, true);
+ 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",
+ "/a/node_modules/b/c/node_modules/d/node_modules/foo.d.ts",
+ "/a/node_modules/b/c/node_modules/d/node_modules/foo/package.json",
+ "/a/node_modules/b/c/node_modules/d/node_modules/foo/index.ts",
+ "/a/node_modules/b/c/node_modules/d/node_modules/foo/index.tsx",
+ "/a/node_modules/b/c/node_modules/d/node_modules/foo/index.d.ts",
+ "/a/node_modules/b/c/node_modules/foo.ts",
+ "/a/node_modules/b/c/node_modules/foo.tsx",
+ "/a/node_modules/b/c/node_modules/foo.d.ts",
+ "/a/node_modules/b/c/node_modules/foo/package.json",
+ "/a/node_modules/b/c/node_modules/foo/index.ts",
+ "/a/node_modules/b/c/node_modules/foo/index.tsx",
+ "/a/node_modules/b/c/node_modules/foo/index.d.ts",
+ "/a/node_modules/b/node_modules/foo.ts",
+ "/a/node_modules/b/node_modules/foo.tsx",
+ "/a/node_modules/b/node_modules/foo.d.ts",
+ "/a/node_modules/b/node_modules/foo/package.json",
+ "/a/node_modules/b/node_modules/foo/index.ts",
+ "/a/node_modules/b/node_modules/foo/index.tsx",
+ "/a/node_modules/b/node_modules/foo/index.d.ts",
+ "/a/node_modules/foo.ts",
+ "/a/node_modules/foo.tsx",
+ "/a/node_modules/foo.d.ts",
+ "/a/node_modules/foo/package.json",
+ "/a/node_modules/foo/index.ts",
+ "/a/node_modules/foo/index.tsx"
+ ]);
+
+ }
});
});
@@ -400,4 +458,21 @@ import b = require("./moduleB.ts");
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /* useCaseSensitiveFileNames */ false, ["moduleD.ts"], []);
})
});
+
+ function notImplemented(name: string): () => any {
+ return () => assert(`${name} is not implemented and should not be called`);
+ }
+
+ describe("ModuleResolutionHost.directoryExists", () => {
+ it("No 'fileExists' calls if containing directory is missing", () => {
+ const host: ModuleResolutionHost = {
+ readFile: notImplemented("readFile"),
+ fileExists: notImplemented("fileExists"),
+ directoryExists: _ => false
+ };
+
+ const result = resolveModuleName("someName", "/a/b/c/d", { moduleResolution: ModuleResolutionKind.NodeJs }, host);
+ assert(!result.resolvedModule);
+ });
+ });
}
\ No newline at end of file
diff --git a/tslint.json b/tslint.json
index 71efb21ad7b..2d2e42d4383 100644
--- a/tslint.json
+++ b/tslint.json
@@ -42,6 +42,7 @@
"boolean-trivia": true,
"type-operator-spacing": true,
"prefer-const": true,
- "no-in-operator": true
+ "no-in-operator": true,
+ "no-increment-decrement": true
}
}