When the imported module is through node_modules and symlink to folder that isnt node_modules (#37387)

* Add tests that fail because of symlink to non common directory node_modules

* When the imported module is through node_modules and symlink to folder that isnt node_modules
Most of the monorepo like scenarios are like this so looking at symlink to decide if file can be imported is essential
Fixes #28689
This commit is contained in:
Sheetal Nandi
2020-03-16 11:15:39 -07:00
committed by GitHub
parent b8baf48043
commit 2458c8a016
6 changed files with 242 additions and 63 deletions
+39 -25
View File
@@ -26,6 +26,8 @@ namespace FourSlash {
files: FourSlashFile[];
symlinks: vfs.FileSet | undefined;
// A mapping from marker names to name/position pairs
markerPositions: ts.Map<Marker>;
@@ -342,6 +344,10 @@ namespace FourSlash {
});
}
if (testData.symlinks) {
this.languageServiceAdapterHost.vfs.apply(testData.symlinks);
}
this.formatCodeSettings = ts.testFormatSettings;
// Open the first file by default
@@ -3767,6 +3773,7 @@ namespace FourSlash {
const files: FourSlashFile[] = [];
// Global options
const globalOptions: { [s: string]: string; } = {};
let symlinks: vfs.FileSet | undefined;
// Marker positions
// Split up the input file by line
@@ -3815,32 +3822,38 @@ namespace FourSlash {
throw new Error("Three-slash line in the middle of four-slash region at line " + i);
}
else if (line.substr(0, 2) === "//") {
// Comment line, check for global/file @options and record them
const match = optionRegex.exec(line.substr(2));
if (match) {
const key = match[1].toLowerCase();
const value = match[2];
if (!ts.contains(fileMetadataNames, key)) {
// Check if the match is already existed in the global options
if (globalOptions[key] !== undefined) {
throw new Error(`Global option '${key}' already exists`);
const possiblySymlinks = Harness.TestCaseParser.parseSymlinkFromTest(line, symlinks);
if (possiblySymlinks) {
symlinks = possiblySymlinks;
}
else {
// Comment line, check for global/file @options and record them
const match = optionRegex.exec(line.substr(2));
if (match) {
const key = match[1].toLowerCase();
const value = match[2];
if (!ts.contains(fileMetadataNames, key)) {
// Check if the match is already existed in the global options
if (globalOptions[key] !== undefined) {
throw new Error(`Global option '${key}' already exists`);
}
globalOptions[key] = value;
}
globalOptions[key] = value;
}
else {
switch (key) {
case MetadataOptionNames.fileName:
// Found an @FileName directive, if this is not the first then create a new subfile
nextFile();
currentFileName = ts.isRootedDiskPath(value) ? value : basePath + "/" + value;
currentFileOptions[key] = value;
break;
case MetadataOptionNames.symlink:
currentFileSymlinks = ts.append(currentFileSymlinks, value);
break;
default:
// Add other fileMetadata flag
currentFileOptions[key] = value;
else {
switch (key) {
case MetadataOptionNames.fileName:
// Found an @FileName directive, if this is not the first then create a new subfile
nextFile();
currentFileName = ts.isRootedDiskPath(value) ? value : basePath + "/" + value;
currentFileOptions[key] = value;
break;
case MetadataOptionNames.symlink:
currentFileSymlinks = ts.append(currentFileSymlinks, value);
break;
default:
// Add other fileMetadata flag
currentFileOptions[key] = value;
}
}
}
}
@@ -3870,6 +3883,7 @@ namespace FourSlash {
markers,
globalOptions,
files,
symlinks,
ranges
};
}
+13 -5
View File
@@ -1128,6 +1128,16 @@ namespace Harness {
const optionRegex = /^[\/]{2}\s*@(\w+)\s*:\s*([^\r\n]*)/gm; // multiple matches on multiple lines
const linkRegex = /^[\/]{2}\s*@link\s*:\s*([^\r\n]*)\s*->\s*([^\r\n]*)/gm; // multiple matches on multiple lines
export function parseSymlinkFromTest(line: string, symlinks: vfs.FileSet | undefined) {
const linkMetaData = linkRegex.exec(line);
linkRegex.lastIndex = 0;
if (!linkMetaData) return undefined;
if (!symlinks) symlinks = {};
symlinks[linkMetaData[2].trim()] = new vfs.Symlink(linkMetaData[1].trim());
return symlinks;
}
export function extractCompilerSettings(content: string): CompilerSettings {
const opts: CompilerSettings = {};
@@ -1163,11 +1173,9 @@ namespace Harness {
for (const line of lines) {
let testMetaData: RegExpExecArray | null;
const linkMetaData = linkRegex.exec(line);
linkRegex.lastIndex = 0;
if (linkMetaData) {
if (!symlinks) symlinks = {};
symlinks[linkMetaData[2].trim()] = new vfs.Symlink(linkMetaData[1].trim());
const possiblySymlinks = parseSymlinkFromTest(line, symlinks);
if (possiblySymlinks) {
symlinks = possiblySymlinks;
}
else if (testMetaData = optionRegex.exec(line)) {
// Comment line, check for global/file @options and record them