( filePath: string, searchStrategy: FileSearchStrategy = "one-up" )
| 89 | }; |
| 90 | |
| 91 | export async function findTestFile( |
| 92 | filePath: string, |
| 93 | searchStrategy: FileSearchStrategy = "one-up" |
| 94 | ): Promise<vscode.Uri | null> { |
| 95 | const fileName: string = filePath.split("/").pop()!; |
| 96 | const fileNameExtension: string = fileName.split(".").pop()!; |
| 97 | const fileNameRaw = fileName.replace(`.${fileNameExtension}`, ""); |
| 98 | |
| 99 | const currentDir: vscode.Uri = vscode.Uri.parse(filePath.replace(fileName, "")); |
| 100 | const rootDir = await getRemixRootFromFileUri(currentDir); |
| 101 | if (!rootDir) { |
| 102 | return null; |
| 103 | } |
| 104 | const rootDirPath = rootDir.path; |
| 105 | // Adds files to ignore when searching for test file |
| 106 | const gitIgnore = await tryReadFile(rootDir.path + "/.gitignore"); |
| 107 | const filesToIgnore = gitIgnore?.split("\n").filter((line) => line !== "" && !line.startsWith("#")); |
| 108 | |
| 109 | const traversedDirs: Set<string> = new Set<string>(); // Track traversed directories |
| 110 | filesToIgnore?.forEach((file) => { |
| 111 | traversedDirs.add(rootDirPath + (file.startsWith("/") ? file : "/" + file)); |
| 112 | }); |
| 113 | traversedDirs.add(rootDir.path + "/.git"); // Ignore .git folder |
| 114 | traversedDirs.add(rootDir.path + "/.cache"); // Ignore .cache folder |
| 115 | |
| 116 | async function searchRecursively(directory: vscode.Uri): Promise<vscode.Uri | null> { |
| 117 | const directoryPath: string = directory.path; |
| 118 | |
| 119 | if (traversedDirs.has(directoryPath)) { |
| 120 | return null; // Exit early if directory has already been traversed |
| 121 | } |
| 122 | // Add directory to traversed directories |
| 123 | traversedDirs.add(directoryPath); |
| 124 | // Read directory and all its folders/files |
| 125 | const files: [string, vscode.FileType][] = await vscode.workspace.fs.readDirectory(directory); |
| 126 | |
| 127 | for (const [file, fileType] of files) { |
| 128 | const fileUri: vscode.Uri = vscode.Uri.joinPath(directory, file); |
| 129 | const isDirectory: boolean = fileType === vscode.FileType.Directory; |
| 130 | |
| 131 | if (isDirectory) { |
| 132 | const foundFile: vscode.Uri | null = await searchRecursively(fileUri); |
| 133 | if (foundFile) { |
| 134 | return foundFile; |
| 135 | } |
| 136 | } else if (file.includes(".test") && file.includes(fileNameRaw)) { |
| 137 | return fileUri; |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | return null; |
| 142 | } |
| 143 | let currentDirectory: vscode.Uri = currentDir; |
| 144 | // Search for test file in the current directory and all subdirectories |
| 145 | if (searchStrategy === "sub") { |
| 146 | const foundFile: vscode.Uri | null = await searchRecursively(currentDirectory); |
| 147 | |
| 148 | return foundFile; |
no test coverage detected