Merge pull request #11495 from Microsoft/includes_glob

Implicitly consider an extensionless file in "includes" to be a recursive directory glob
This commit is contained in:
Andy
2016-10-31 13:56:10 -07:00
committed by GitHub
5 changed files with 200 additions and 240 deletions

View File

@@ -1008,9 +1008,7 @@ namespace ts {
function convertTypingOptionsFromJsonWorker(jsonOptions: any,
basePath: string, errors: Diagnostic[], configFileName?: string): TypingOptions {
const options: TypingOptions = getBaseFileName(configFileName) === "jsconfig.json"
? { enableAutoDiscovery: true, include: [], exclude: [] }
: { enableAutoDiscovery: false, include: [], exclude: [] };
const options: TypingOptions = { enableAutoDiscovery: getBaseFileName(configFileName) === "jsconfig.json", include: [], exclude: [] };
convertOptionsFromJson(typingOptionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_typing_option_0, errors);
return options;
}
@@ -1263,12 +1261,13 @@ namespace ts {
/**
* Gets directories in a set of include patterns that should be watched for changes.
*/
function getWildcardDirectories(include: string[], exclude: string[], path: string, useCaseSensitiveFileNames: boolean) {
function getWildcardDirectories(include: string[], exclude: string[], path: string, useCaseSensitiveFileNames: boolean): Map<WatchDirectoryFlags> {
// We watch a directory recursively if it contains a wildcard anywhere in a directory segment
// of the pattern:
//
// /a/b/**/d - Watch /a/b recursively to catch changes to any d in any subfolder recursively
// /a/b/*/d - Watch /a/b recursively to catch any d in any immediate subfolder, even if a new subfolder is added
// /a/b - Watch /a/b recursively to catch changes to anything in any recursive subfoler
//
// We watch a directory without recursion if it contains a wildcard in the file segment of
// the pattern:
@@ -1281,15 +1280,14 @@ namespace ts {
if (include !== undefined) {
const recursiveKeys: string[] = [];
for (const file of include) {
const name = normalizePath(combinePaths(path, file));
if (excludeRegex && excludeRegex.test(name)) {
const spec = normalizePath(combinePaths(path, file));
if (excludeRegex && excludeRegex.test(spec)) {
continue;
}
const match = wildcardDirectoryPattern.exec(name);
const match = getWildcardDirectoryFromSpec(spec, useCaseSensitiveFileNames);
if (match) {
const key = useCaseSensitiveFileNames ? match[0] : match[0].toLowerCase();
const flags = watchRecursivePattern.test(name) ? WatchDirectoryFlags.Recursive : WatchDirectoryFlags.None;
const { key, flags } = match;
const existingFlags = wildcardDirectories[key];
if (existingFlags === undefined || existingFlags < flags) {
wildcardDirectories[key] = flags;
@@ -1313,6 +1311,20 @@ namespace ts {
return wildcardDirectories;
}
function getWildcardDirectoryFromSpec(spec: string, useCaseSensitiveFileNames: boolean): { key: string, flags: WatchDirectoryFlags } | undefined {
const match = wildcardDirectoryPattern.exec(spec);
if (match) {
return {
key: useCaseSensitiveFileNames ? match[0] : match[0].toLowerCase(),
flags: watchRecursivePattern.test(spec) ? WatchDirectoryFlags.Recursive : WatchDirectoryFlags.None
};
}
if (isImplicitGlob(spec)) {
return { key: spec, flags: WatchDirectoryFlags.Recursive };
}
return undefined;
}
/**
* Determines whether a literal or wildcard file has already been included that has a higher
* extension priority.

View File

@@ -1312,7 +1312,7 @@ namespace ts {
*/
export function getDirectoryPath(path: Path): Path;
export function getDirectoryPath(path: string): string;
export function getDirectoryPath(path: string): any {
export function getDirectoryPath(path: string): string {
return path.substr(0, Math.max(getRootLength(path), path.lastIndexOf(directorySeparator)));
}
@@ -1572,6 +1572,10 @@ namespace ts {
return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos;
}
export function hasExtension(fileName: string): boolean {
return getBaseFileName(fileName).indexOf(".") >= 0;
}
export function fileExtensionIs(path: string, extension: string): boolean {
return path.length > extension.length && endsWith(path, extension);
}
@@ -1617,73 +1621,21 @@ namespace ts {
let pattern = "";
let hasWrittenSubpattern = false;
spec: for (const spec of specs) {
for (const spec of specs) {
if (!spec) {
continue;
}
let subpattern = "";
let hasRecursiveDirectoryWildcard = false;
let hasWrittenComponent = false;
const components = getNormalizedPathComponents(spec, basePath);
if (usage !== "exclude" && components[components.length - 1] === "**") {
continue spec;
}
// getNormalizedPathComponents includes the separator for the root component.
// We need to remove to create our regex correctly.
components[0] = removeTrailingDirectorySeparator(components[0]);
let optionalCount = 0;
for (let component of components) {
if (component === "**") {
if (hasRecursiveDirectoryWildcard) {
continue spec;
}
subpattern += doubleAsteriskRegexFragment;
hasRecursiveDirectoryWildcard = true;
hasWrittenComponent = true;
}
else {
if (usage === "directories") {
subpattern += "(";
optionalCount++;
}
if (hasWrittenComponent) {
subpattern += directorySeparator;
}
if (usage !== "exclude") {
// The * and ? wildcards should not match directories or files that start with . if they
// appear first in a component. Dotted directories and files can be included explicitly
// like so: **/.*/.*
if (component.charCodeAt(0) === CharacterCodes.asterisk) {
subpattern += "([^./]" + singleAsteriskRegexFragment + ")?";
component = component.substr(1);
}
else if (component.charCodeAt(0) === CharacterCodes.question) {
subpattern += "[^./]";
component = component.substr(1);
}
}
subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
hasWrittenComponent = true;
}
}
while (optionalCount > 0) {
subpattern += ")?";
optionalCount--;
const subPattern = getSubPatternFromSpec(spec, basePath, usage, singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter);
if (subPattern === undefined) {
continue;
}
if (hasWrittenSubpattern) {
pattern += "|";
}
pattern += "(" + subpattern + ")";
pattern += "(" + subPattern + ")";
hasWrittenSubpattern = true;
}
@@ -1691,7 +1643,83 @@ namespace ts {
return undefined;
}
return "^(" + pattern + (usage === "exclude" ? ")($|/)" : ")$");
// If excluding, match "foo/bar/baz...", but if including, only allow "foo".
const terminator = usage === "exclude" ? "($|/)" : "$";
return `^(${pattern})${terminator}`;
}
/**
* An "includes" path "foo" is implicitly a glob "foo/** /*" (without the space) if its last component has no extension,
* and does not contain any glob characters itself.
*/
export function isImplicitGlob(lastPathComponent: string): boolean {
return !/[.*?]/.test(lastPathComponent);
}
function getSubPatternFromSpec(spec: string, basePath: string, usage: "files" | "directories" | "exclude", singleAsteriskRegexFragment: string, doubleAsteriskRegexFragment: string, replaceWildcardCharacter: (match: string) => string): string | undefined {
let subpattern = "";
let hasRecursiveDirectoryWildcard = false;
let hasWrittenComponent = false;
const components = getNormalizedPathComponents(spec, basePath);
const lastComponent = lastOrUndefined(components);
if (usage !== "exclude" && lastComponent === "**") {
return undefined;
}
// getNormalizedPathComponents includes the separator for the root component.
// We need to remove to create our regex correctly.
components[0] = removeTrailingDirectorySeparator(components[0]);
if (isImplicitGlob(lastComponent)) {
components.push("**", "*");
}
let optionalCount = 0;
for (let component of components) {
if (component === "**") {
if (hasRecursiveDirectoryWildcard) {
return undefined;
}
subpattern += doubleAsteriskRegexFragment;
hasRecursiveDirectoryWildcard = true;
}
else {
if (usage === "directories") {
subpattern += "(";
optionalCount++;
}
if (hasWrittenComponent) {
subpattern += directorySeparator;
}
if (usage !== "exclude") {
// The * and ? wildcards should not match directories or files that start with . if they
// appear first in a component. Dotted directories and files can be included explicitly
// like so: **/.*/.*
if (component.charCodeAt(0) === CharacterCodes.asterisk) {
subpattern += "([^./]" + singleAsteriskRegexFragment + ")?";
component = component.substr(1);
}
else if (component.charCodeAt(0) === CharacterCodes.question) {
subpattern += "[^./]";
component = component.substr(1);
}
}
subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
}
hasWrittenComponent = true;
}
while (optionalCount > 0) {
subpattern += ")?";
optionalCount--;
}
return subpattern;
}
function replaceWildCardCharacterFiles(match: string) {
@@ -1778,6 +1806,7 @@ namespace ts {
function getBasePaths(path: string, includes: string[], useCaseSensitiveFileNames: boolean) {
// Storage for our results in the form of literal paths (e.g. the paths as written by the user).
const basePaths: string[] = [path];
if (includes) {
// Storage for literal base paths amongst the include patterns.
const includeBasePaths: string[] = [];
@@ -1785,14 +1814,8 @@ namespace ts {
// We also need to check the relative paths by converting them to absolute and normalizing
// in case they escape the base path (e.g "..\somedirectory")
const absolute: string = isRootedDiskPath(include) ? include : normalizePath(combinePaths(path, include));
const wildcardOffset = indexOfAnyCharCode(absolute, wildcardCharCodes);
const includeBasePath = wildcardOffset < 0
? removeTrailingDirectorySeparator(getDirectoryPath(absolute))
: absolute.substring(0, absolute.lastIndexOf(directorySeparator, wildcardOffset));
// Append the literal and canonical candidate base paths.
includeBasePaths.push(includeBasePath);
includeBasePaths.push(getIncludeBasePath(absolute));
}
// Sort the offsets array using either the literal or canonical path representations.
@@ -1800,21 +1823,27 @@ namespace ts {
// Iterate over each include base path and include unique base paths that are not a
// subpath of an existing base path
include: for (let i = 0; i < includeBasePaths.length; i++) {
const includeBasePath = includeBasePaths[i];
for (let j = 0; j < basePaths.length; j++) {
if (containsPath(basePaths[j], includeBasePath, path, !useCaseSensitiveFileNames)) {
continue include;
}
for (const includeBasePath of includeBasePaths) {
if (ts.every(basePaths, basePath => !containsPath(basePath, includeBasePath, path, !useCaseSensitiveFileNames))) {
basePaths.push(includeBasePath);
}
basePaths.push(includeBasePath);
}
}
return basePaths;
}
function getIncludeBasePath(absolute: string): string {
const wildcardOffset = indexOfAnyCharCode(absolute, wildcardCharCodes);
if (wildcardOffset < 0) {
// No "*" or "?" in the path
return !hasExtension(absolute)
? absolute
: removeTrailingDirectorySeparator(getDirectoryPath(absolute));
}
return absolute.substring(0, absolute.lastIndexOf(directorySeparator, wildcardOffset));
}
export function ensureScriptKind(fileName: string, scriptKind?: ScriptKind): ScriptKind {
// Using scriptKind as a condition handles both:
// - 'scriptKind' is unspecified and thus it is `undefined`

View File

@@ -971,10 +971,6 @@ namespace ts {
return sortAndDeduplicateDiagnostics(allDiagnostics);
}
function hasExtension(fileName: string): boolean {
return getBaseFileName(fileName).indexOf(".") >= 0;
}
function processRootFile(fileName: string, isDefaultLib: boolean) {
processSourceFile(normalizePath(fileName), isDefaultLib);
}

View File

@@ -3145,6 +3145,7 @@ namespace ts {
Pretty,
}
/** Either a parsed command line or a parsed tsconfig.json */
export interface ParsedCommandLine {
options: CompilerOptions;
typingOptions?: TypingOptions;

View File

@@ -91,6 +91,12 @@ namespace ts {
const defaultExcludes = ["node_modules", "bower_components", "jspm_packages"];
function assertParsed(actual: ts.ParsedCommandLine, expected: ts.ParsedCommandLine): void {
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
}
describe("matchFiles", () => {
describe("with literal file list", () => {
it("without exclusions", () => {
@@ -110,9 +116,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("missing files are still present", () => {
const json = {
@@ -131,9 +135,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("are not removed due to excludes", () => {
const json = {
@@ -155,9 +157,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
});
@@ -179,9 +179,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with non .ts file extensions are excluded", () => {
const json = {
@@ -200,9 +198,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with missing files are excluded", () => {
const json = {
@@ -221,9 +217,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with literal excludes", () => {
const json = {
@@ -244,9 +238,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with wildcard excludes", () => {
const json = {
@@ -274,9 +266,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with recursive excludes", () => {
const json = {
@@ -303,9 +293,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with case sensitive exclude", () => {
const json = {
@@ -325,9 +313,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseSensitiveHost, caseSensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with common package folders and no exclusions", () => {
const json = {
@@ -349,9 +335,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with common package folders and exclusions", () => {
const json = {
@@ -378,9 +362,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with common package folders and empty exclude", () => {
const json = {
@@ -406,9 +388,7 @@ namespace ts {
wildcardDirectories: {},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
});
@@ -432,9 +412,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("`*` matches only ts files", () => {
const json = {
@@ -455,9 +433,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("`?` matches only a single character", () => {
const json = {
@@ -477,9 +453,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with recursive directory", () => {
const json = {
@@ -501,9 +475,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with multiple recursive directories", () => {
const json = {
@@ -527,9 +499,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("case sensitive", () => {
const json = {
@@ -548,9 +518,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseSensitiveHost, caseSensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with missing files are excluded", () => {
const json = {
@@ -570,9 +538,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("always include literal files", () => {
const json = {
@@ -597,9 +563,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("exclude folders", () => {
const json = {
@@ -624,9 +588,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with common package folders and no exclusions", () => {
const json = {
@@ -645,9 +607,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with common package folders and exclusions", () => {
const json = {
@@ -671,9 +631,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with common package folders and empty exclude", () => {
const json = {
@@ -696,9 +654,7 @@ namespace ts {
},
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("exclude .js files when allowJs=false", () => {
const json = {
@@ -723,9 +679,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("include .js files when allowJs=true", () => {
const json = {
@@ -750,9 +704,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("include explicitly listed .min.js files when allowJs=true", () => {
const json = {
@@ -777,9 +729,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("include paths outside of the project", () => {
const json = {
@@ -803,9 +753,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("include paths outside of the project using relative paths", () => {
const json = {
@@ -828,9 +776,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("exclude paths outside of the project using relative paths", () => {
const json = {
@@ -851,9 +797,7 @@ namespace ts {
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("include files with .. in their name", () => {
const json = {
@@ -873,9 +817,7 @@ namespace ts {
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("exclude files with .. in their name", () => {
const json = {
@@ -897,9 +839,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with jsx=none, allowJs=false", () => {
const json = {
@@ -922,9 +862,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with jsx=preserve, allowJs=false", () => {
const json = {
@@ -949,9 +887,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with jsx=none, allowJs=true", () => {
const json = {
@@ -976,9 +912,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with jsx=preserve, allowJs=true", () => {
const json = {
@@ -1005,9 +939,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("exclude .min.js files using wildcards", () => {
const json = {
@@ -1034,9 +966,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
describe("with trailing recursive directory", () => {
it("in includes", () => {
@@ -1056,9 +986,7 @@ namespace ts {
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("in excludes", () => {
const json = {
@@ -1079,9 +1007,7 @@ namespace ts {
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
});
describe("with multiple recursive directory patterns", () => {
@@ -1102,9 +1028,7 @@ namespace ts {
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("in excludes", () => {
const json = {
@@ -1131,9 +1055,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
});
@@ -1155,9 +1077,7 @@ namespace ts {
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("in includes after a subdirectory", () => {
@@ -1177,9 +1097,7 @@ namespace ts {
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("in excludes immediately after", () => {
@@ -1207,9 +1125,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("in excludes after a subdirectory", () => {
@@ -1237,9 +1153,25 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
});
describe("with implicit globbification", () => {
it("Expands 'z' to 'z/**/*'", () => {
const json = {
include: ["z"]
};
const expected: ts.ParsedCommandLine = {
options: {},
errors: [],
fileNames: [ "a.ts", "aba.ts", "abz.ts", "b.ts", "bba.ts", "bbz.ts" ].map(x => `c:/dev/z/${x}`),
wildcardDirectories: {
"c:/dev/z": ts.WatchDirectoryFlags.Recursive
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
assertParsed(actual, expected);
});
});
});
@@ -1264,9 +1196,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
describe("that are explicitly included", () => {
it("without wildcards", () => {
@@ -1286,9 +1216,7 @@ namespace ts {
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with recursive wildcards that match directories", () => {
const json = {
@@ -1310,9 +1238,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with recursive wildcards that match nothing", () => {
const json = {
@@ -1334,9 +1260,7 @@ namespace ts {
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
it("with wildcard excludes that implicitly exclude dotted files", () => {
const json = {
@@ -1357,9 +1281,7 @@ namespace ts {
wildcardDirectories: {}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
assertParsed(actual, expected);
});
});
});