提交 56c6946b 编写于 作者: R Rob Lourens

Fix issue with searching using workspace folder name. Add file search integration tests

Fix #97352
上级 306235b1
......@@ -183,7 +183,7 @@ export function resultIsMatch(result: ITextSearchResult): result is ITextSearchM
}
export interface IProgressMessage {
message?: string;
message: string;
}
export type ISearchProgressItem = IFileMatch | IProgressMessage;
......@@ -192,8 +192,8 @@ export function isFileMatch(p: ISearchProgressItem): p is IFileMatch {
return !!(<IFileMatch>p).resource;
}
export function isProgressMessage(p: ISearchProgressItem): p is IProgressMessage {
return !isFileMatch(p);
export function isProgressMessage(p: ISearchProgressItem | ISerializedSearchProgressItem): p is IProgressMessage {
return !!(p as IProgressMessage).message;
}
export interface ISearchCompleteStats {
......@@ -468,7 +468,7 @@ export interface IRawFileMatch {
*
* If not given, the search algorithm should use `relativePath`.
*/
searchPath?: string;
searchPath: string | undefined;
}
export interface ISearchEngine<T> {
......
......@@ -24,9 +24,8 @@ import { IFileQuery, IFolderQuery, IProgressMessage, ISearchEngineStats, IRawFil
import { spawnRipgrepCmd } from './ripgrepFileSearch';
import { prepareQuery } from 'vs/base/common/fuzzyScorer';
interface IDirectoryEntry {
interface IDirectoryEntry extends IRawFileMatch {
base: string;
relativePath: string;
basename: string;
}
......@@ -122,7 +121,7 @@ export class FileWalker {
}
// File: Check for match on file pattern and include pattern
this.matchFile(onResult, { relativePath: extraFilePath.fsPath /* no workspace relative path */ });
this.matchFile(onResult, { relativePath: extraFilePath.fsPath /* no workspace relative path */, searchPath: undefined });
});
this.cmdSW = StopWatch.create(false);
......@@ -260,7 +259,7 @@ export class FileWalker {
}
// TODO: Optimize siblings clauses with ripgrep here.
this.addDirectoryEntries(tree, rootFolder, relativeFiles, onResult);
this.addDirectoryEntries(folderQuery, tree, rootFolder, relativeFiles, onResult);
if (last) {
this.matchDirectoryTree(tree, rootFolder, onResult);
......@@ -389,13 +388,17 @@ export class FileWalker {
return tree;
}
private addDirectoryEntries({ pathToEntries }: IDirectoryTree, base: string, relativeFiles: string[], onResult: (result: IRawFileMatch) => void) {
private addDirectoryEntries(folderQuery: IFolderQuery, { pathToEntries }: IDirectoryTree, base: string, relativeFiles: string[], onResult: (result: IRawFileMatch) => void) {
// Support relative paths to files from a root resource (ignores excludes)
if (relativeFiles.indexOf(this.filePattern) !== -1) {
this.matchFile(onResult, { base: base, relativePath: this.filePattern });
this.matchFile(onResult, {
base,
relativePath: this.filePattern,
searchPath: this.getSearchPath(folderQuery, this.filePattern)
});
}
function add(relativePath: string) {
const add = (relativePath: string) => {
const basename = path.basename(relativePath);
const dirname = path.dirname(relativePath);
let entries = pathToEntries[dirname];
......@@ -406,9 +409,10 @@ export class FileWalker {
entries.push({
base,
relativePath,
basename
basename,
searchPath: this.getSearchPath(folderQuery, relativePath),
});
}
};
relativeFiles.forEach(add);
}
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { getPathFromAmdModule } from 'vs/base/common/amd';
import * as path from 'vs/base/common/path';
import { URI } from 'vs/base/common/uri';
import { IFileQuery, IFolderQuery, ISerializedSearchProgressItem, isProgressMessage, QueryType } from 'vs/workbench/services/search/common/search';
import { SearchService } from 'vs/workbench/services/search/node/rawSearchService';
const TEST_FIXTURES = path.normalize(getPathFromAmdModule(require, './fixtures'));
const TEST_FIXTURES2 = path.normalize(getPathFromAmdModule(require, './fixtures2'));
const EXAMPLES_FIXTURES = path.join(TEST_FIXTURES, 'examples');
const MORE_FIXTURES = path.join(TEST_FIXTURES, 'more');
const TEST_ROOT_FOLDER: IFolderQuery = { folder: URI.file(TEST_FIXTURES) };
const ROOT_FOLDER_QUERY: IFolderQuery[] = [
TEST_ROOT_FOLDER
];
const MULTIROOT_QUERIES: IFolderQuery[] = [
{ folder: URI.file(EXAMPLES_FIXTURES), folderName: 'examples_folder' },
{ folder: URI.file(MORE_FIXTURES) }
];
async function doSearchTest(query: IFileQuery, expectedResultCount: number | Function): Promise<void> {
const svc = new SearchService();
const results: ISerializedSearchProgressItem[] = [];
await svc.doFileSearch(query, e => {
if (!isProgressMessage(e)) {
if (Array.isArray(e)) {
results.push(...e);
} else {
results.push(e);
}
}
});
assert.equal(results.length, expectedResultCount, `rg ${results.length} !== ${expectedResultCount}`);
}
suite('FileSearch-integration', function () {
this.timeout(1000 * 60); // increase timeout for this suite
test('File - simple', () => {
const config: IFileQuery = {
type: QueryType.File,
folderQueries: ROOT_FOLDER_QUERY
};
return doSearchTest(config, 14);
});
test('File - filepattern', () => {
const config: IFileQuery = {
type: QueryType.File,
folderQueries: ROOT_FOLDER_QUERY,
filePattern: 'anotherfile'
};
return doSearchTest(config, 1);
});
test('File - exclude', () => {
const config: IFileQuery = {
type: QueryType.File,
folderQueries: ROOT_FOLDER_QUERY,
filePattern: 'file',
excludePattern: { '**/anotherfolder/**': true }
};
return doSearchTest(config, 2);
});
test('File - multiroot', () => {
const config: IFileQuery = {
type: QueryType.File,
folderQueries: MULTIROOT_QUERIES,
filePattern: 'file',
excludePattern: { '**/anotherfolder/**': true }
};
return doSearchTest(config, 2);
});
test('File - multiroot with folder name', () => {
const config: IFileQuery = {
type: QueryType.File,
folderQueries: MULTIROOT_QUERIES,
filePattern: 'examples_folder anotherfile'
};
return doSearchTest(config, 1);
});
test('File - multiroot with folder name and sibling exclude', () => {
const config: IFileQuery = {
type: QueryType.File,
folderQueries: [
{ folder: URI.file(TEST_FIXTURES), folderName: 'folder1' },
{ folder: URI.file(TEST_FIXTURES2) }
],
filePattern: 'folder1 site',
excludePattern: { '*.css': { when: '$(basename).less' } }
};
return doSearchTest(config, 1);
});
});
......@@ -83,6 +83,7 @@ suite('RawSearchService', () => {
const rawMatch: IRawFileMatch = {
base: path.normalize('/some'),
relativePath: 'where',
searchPath: undefined
};
const match: ISerializedFileMatch = {
......@@ -232,7 +233,8 @@ suite('RawSearchService', () => {
base: path.normalize('/some/where'),
relativePath,
basename: relativePath,
size: 3
size: 3,
searchPath: undefined
}));
const Engine = TestSearchEngine.bind(null, () => matches.shift()!);
const service = new RawSearchService();
......@@ -291,7 +293,8 @@ suite('RawSearchService', () => {
base: path.normalize('/some/where'),
relativePath,
basename: relativePath,
size: 3
size: 3,
searchPath: undefined
}));
const Engine = TestSearchEngine.bind(null, () => matches.shift()!);
const service = new RawSearchService();
......@@ -340,6 +343,7 @@ suite('RawSearchService', () => {
matches.push({
base: path.normalize('/some/where'),
relativePath: 'bc',
searchPath: undefined
});
const results: any[] = [];
const cb: IProgressCallback = value => {
......
......@@ -46,7 +46,7 @@ function doSearchTest(query: ITextQuery, expectedResultCount: number | Function)
});
}
suite('Search-integration', function () {
suite('TextSearch-integration', function () {
this.timeout(1000 * 60); // increase timeout for this suite
test('Text: GameOfLife', () => {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册