mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-28 04:23:32 +01:00
Use 'dir' on Windows
This commit is contained in:
@@ -26,6 +26,7 @@ import {IRawFileMatch, ISerializedSearchComplete, IRawSearch, ISearchEngine} fro
|
||||
enum Traversal {
|
||||
Node = 1,
|
||||
MacFind,
|
||||
WindowsDir
|
||||
}
|
||||
|
||||
interface IDirectoryEntry {
|
||||
@@ -76,7 +77,6 @@ export class FileWalker {
|
||||
this.errors = [];
|
||||
|
||||
if (this.filePattern) {
|
||||
this.filePattern = this.filePattern.replace(/\\/g, '/'); // Normalize file patterns to forward slashes
|
||||
this.normalizedFilePatternLowercase = strings.stripWildcards(this.filePattern).toLowerCase();
|
||||
}
|
||||
}
|
||||
@@ -98,8 +98,7 @@ export class FileWalker {
|
||||
if (exists) {
|
||||
this.resultCount++;
|
||||
onResult({
|
||||
absolutePath: this.filePattern,
|
||||
pathLabel: this.filePattern,
|
||||
path: this.filePattern,
|
||||
size
|
||||
});
|
||||
|
||||
@@ -117,21 +116,31 @@ export class FileWalker {
|
||||
}
|
||||
|
||||
// File: Check for match on file pattern and include pattern
|
||||
this.matchFile(onResult, extraFilePath, extraFilePath /* no workspace relative path */);
|
||||
this.matchFile(onResult, null, extraFilePath /* no workspace relative path */);
|
||||
});
|
||||
}
|
||||
|
||||
let traverse = this.nodeJSTraversal;
|
||||
if (!this.maxFilesize && platform.isMacintosh) {
|
||||
this.traversal = Traversal.MacFind;
|
||||
traverse = this.macFindTraversal;
|
||||
if (!this.maxFilesize) {
|
||||
if (platform.isMacintosh) {
|
||||
this.traversal = Traversal.MacFind;
|
||||
traverse = this.macFindTraversal;
|
||||
} else if (platform.isWindows) {
|
||||
this.traversal = Traversal.WindowsDir;
|
||||
traverse = this.windowsDirTraversal;
|
||||
}
|
||||
}
|
||||
|
||||
const isNodeTraversal = traverse === this.nodeJSTraversal;
|
||||
if (!isNodeTraversal) {
|
||||
this.cmdForkStartTime = Date.now();
|
||||
}
|
||||
|
||||
// For each root folder
|
||||
flow.parallel(rootFolders, (rootFolder, rootFolderDone: (err?: Error) => void) => {
|
||||
traverse.call(this, rootFolder, onResult, err => {
|
||||
if (err) {
|
||||
if (traverse === this.nodeJSTraversal) {
|
||||
if (isNodeTraversal) {
|
||||
rootFolderDone(err);
|
||||
} else {
|
||||
// fallback
|
||||
@@ -149,9 +158,8 @@ export class FileWalker {
|
||||
}
|
||||
|
||||
private macFindTraversal(rootFolder: string, onResult: (result: IRawFileMatch) => void, done: (err?: Error) => void): void {
|
||||
this.cmdForkStartTime = Date.now();
|
||||
const cmd = childProcess.spawn('find', ['-L', '.', '-type', 'f'], { cwd: rootFolder });
|
||||
this.readStdout(cmd, (err: Error, stdout?: string) => {
|
||||
this.readStdout(cmd, 'utf8', (err: Error, stdout?: string) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
return;
|
||||
@@ -166,23 +174,38 @@ export class FileWalker {
|
||||
relativeFiles.pop();
|
||||
}
|
||||
|
||||
this.cmdResultCount = relativeFiles.length;
|
||||
|
||||
// Support relative paths to files from a root resource (ignores excludes)
|
||||
if (relativeFiles.indexOf(this.filePattern) !== -1) {
|
||||
this.matchFile(onResult, [rootFolder, this.filePattern].join(paths.sep), this.filePattern);
|
||||
}
|
||||
|
||||
const tree = this.buildDirectoryTree(relativeFiles);
|
||||
this.matchDirectoryTree(rootFolder, tree, onResult);
|
||||
this.matchFiles(rootFolder, relativeFiles, onResult);
|
||||
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
private readStdout(cmd: childProcess.ChildProcess, cb: (err: Error, stdout?: string) => void): void {
|
||||
private windowsDirTraversal(rootFolder: string, onResult: (result: IRawFileMatch) => void, done: (err?: Error) => void): void {
|
||||
const cmd = childProcess.spawn('cmd', ['/U', '/c', 'dir', '/s', '/b', '/a-d'], { cwd: rootFolder });
|
||||
this.readStdout(cmd, 'ucs2', (err: Error, stdout?: string) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
return;
|
||||
}
|
||||
|
||||
const relativeFiles = stdout.split(`\r\n${rootFolder}\\`);
|
||||
relativeFiles[0] = relativeFiles[0].trim().substr(rootFolder.length + 1);
|
||||
const n = relativeFiles.length;
|
||||
relativeFiles[n - 1] = relativeFiles[n - 1].trim();
|
||||
if (!relativeFiles[n - 1]) {
|
||||
relativeFiles.pop();
|
||||
}
|
||||
|
||||
this.matchFiles(rootFolder, relativeFiles, onResult);
|
||||
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
private readStdout(cmd: childProcess.ChildProcess, encoding: string, cb: (err: Error, stdout?: string) => void): void {
|
||||
let done = (err: Error, stdout?: string) => {
|
||||
done = () => {};
|
||||
this.cmdForkResultTime = Date.now();
|
||||
cb(err, stdout);
|
||||
};
|
||||
|
||||
@@ -195,10 +218,9 @@ export class FileWalker {
|
||||
|
||||
cmd.on('close', code => {
|
||||
if (code !== 0) {
|
||||
done(new Error(`find failed with error code ${code}: ${this.decodeData(stderr)}`));
|
||||
done(new Error(`find failed with error code ${code}: ${this.decodeData(stderr, encoding)}`));
|
||||
} else {
|
||||
this.cmdForkResultTime = Date.now();
|
||||
done(null, this.decodeData(stdout));
|
||||
done(null, this.decodeData(stdout, encoding));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -211,10 +233,21 @@ export class FileWalker {
|
||||
return buffers;
|
||||
}
|
||||
|
||||
private decodeData(buffers: Buffer[]): string {
|
||||
const decoder = new StringDecoder('utf8');
|
||||
return buffers.map(data => decoder.write(data))
|
||||
.reduce((all, current) => all + current, '');
|
||||
private decodeData(buffers: Buffer[], encoding: string): string {
|
||||
const decoder = new StringDecoder(encoding);
|
||||
return buffers.map(buffer => decoder.write(buffer)).join('');
|
||||
}
|
||||
|
||||
private matchFiles(rootFolder: string, relativeFiles: string[], onResult: (result: IRawFileMatch) => void) {
|
||||
this.cmdResultCount = relativeFiles.length;
|
||||
|
||||
// Support relative paths to files from a root resource (ignores excludes)
|
||||
if (relativeFiles.indexOf(this.filePattern) !== -1) {
|
||||
this.matchFile(onResult, rootFolder, this.filePattern);
|
||||
}
|
||||
|
||||
const tree = this.buildDirectoryTree(relativeFiles);
|
||||
this.matchDirectoryTree(rootFolder, tree, onResult);
|
||||
}
|
||||
|
||||
private buildDirectoryTree(relativeFilePaths: string[]): IDirectoryTree {
|
||||
@@ -248,7 +281,7 @@ export class FileWalker {
|
||||
self.directoriesWalked++;
|
||||
for (let i = 0, n = entries.length; i < n; i++) {
|
||||
const entry = entries[i];
|
||||
const relativePath = entry.relativePath; // assumes slashes as separator
|
||||
const relativePath = entry.relativePath;
|
||||
|
||||
// Check exclude pattern
|
||||
// If the user searches for the exact file name, we adjust the glob matching
|
||||
@@ -267,22 +300,22 @@ export class FileWalker {
|
||||
continue; // ignore file if its path matches with the file pattern because that is already matched above
|
||||
}
|
||||
|
||||
self.matchFile(onResult, [rootFolder, relativePath].join(paths.sep), relativePath);
|
||||
self.matchFile(onResult, rootFolder, relativePath);
|
||||
}
|
||||
};
|
||||
}
|
||||
matchDirectory(rootEntries);
|
||||
}
|
||||
|
||||
private nodeJSTraversal(absolutePath: string, onResult: (result: IRawFileMatch) => void, done: (err?: Error) => void): void {
|
||||
private nodeJSTraversal(rootFolder: string, onResult: (result: IRawFileMatch) => void, done: (err?: Error) => void): void {
|
||||
this.directoriesWalked++;
|
||||
extfs.readdir(absolutePath, (error: Error, files: string[]) => {
|
||||
extfs.readdir(rootFolder, (error: Error, files: string[]) => {
|
||||
if (error || this.isCanceled || this.isLimitHit) {
|
||||
return done();
|
||||
}
|
||||
|
||||
// Support relative paths to files from a root resource (ignores excludes)
|
||||
return this.checkFilePatternRelativeMatch(absolutePath, (match, size) => {
|
||||
return this.checkFilePatternRelativeMatch(rootFolder, (match, size) => {
|
||||
if (this.isCanceled || this.isLimitHit) {
|
||||
return done();
|
||||
}
|
||||
@@ -291,13 +324,13 @@ export class FileWalker {
|
||||
if (match) {
|
||||
this.resultCount++;
|
||||
onResult({
|
||||
absolutePath: match,
|
||||
pathLabel: this.filePattern,
|
||||
base: rootFolder,
|
||||
path: this.filePattern,
|
||||
size
|
||||
});
|
||||
}
|
||||
|
||||
return this.doWalk(paths.normalize(absolutePath), '', files, onResult, done);
|
||||
return this.doWalk(rootFolder, '', files, onResult, done);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -340,7 +373,7 @@ export class FileWalker {
|
||||
});
|
||||
}
|
||||
|
||||
private doWalk(absolutePath: string, relativeParentPathWithSlashes: string, files: string[], onResult: (result: IRawFileMatch) => void, done: (error: Error) => void): void {
|
||||
private doWalk(rootFolder: string, relativeParentPath: string, files: string[], onResult: (result: IRawFileMatch) => void, done: (error: Error) => void): void {
|
||||
|
||||
// Execute tasks on each file in parallel to optimize throughput
|
||||
flow.parallel(files, (file: string, clb: (error: Error) => void): void => {
|
||||
@@ -359,13 +392,13 @@ export class FileWalker {
|
||||
}
|
||||
|
||||
// Check exclude pattern
|
||||
let currentRelativePathWithSlashes = relativeParentPathWithSlashes ? [relativeParentPathWithSlashes, file].join('/') : file;
|
||||
if (this.excludePattern(currentRelativePathWithSlashes, () => siblings)) {
|
||||
let currentRelativePath = relativeParentPath ? [relativeParentPath, file].join(paths.sep) : file;
|
||||
if (this.excludePattern(currentRelativePath, () => siblings)) {
|
||||
return clb(null);
|
||||
}
|
||||
|
||||
// Use lstat to detect links
|
||||
let currentAbsolutePath = [absolutePath, file].join(paths.sep);
|
||||
let currentAbsolutePath = [rootFolder, currentRelativePath].join(paths.sep);
|
||||
fs.lstat(currentAbsolutePath, (error, lstat) => {
|
||||
if (error || this.isCanceled || this.isLimitHit) {
|
||||
return clb(null);
|
||||
@@ -401,7 +434,7 @@ export class FileWalker {
|
||||
return clb(null);
|
||||
}
|
||||
|
||||
this.doWalk(currentAbsolutePath, currentRelativePathWithSlashes, children, onResult, clb);
|
||||
this.doWalk(rootFolder, currentRelativePath, children, onResult, clb);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -409,7 +442,7 @@ export class FileWalker {
|
||||
// File: Check for match on file pattern and include pattern
|
||||
else {
|
||||
this.filesWalked++;
|
||||
if (currentRelativePathWithSlashes === this.filePattern) {
|
||||
if (currentRelativePath === this.filePattern) {
|
||||
return clb(null); // ignore file if its path matches with the file pattern because checkFilePatternRelativeMatch() takes care of those
|
||||
}
|
||||
|
||||
@@ -417,7 +450,7 @@ export class FileWalker {
|
||||
return clb(null); // ignore file if max file size is hit
|
||||
}
|
||||
|
||||
this.matchFile(onResult, currentAbsolutePath, currentRelativePathWithSlashes, stat.size);
|
||||
this.matchFile(onResult, rootFolder, currentRelativePath, stat.size);
|
||||
}
|
||||
|
||||
// Unwind
|
||||
@@ -433,8 +466,8 @@ export class FileWalker {
|
||||
});
|
||||
}
|
||||
|
||||
private matchFile(onResult: (result: IRawFileMatch) => void, absolutePath: string, relativePathWithSlashes: string, size?: number): void {
|
||||
if (this.isFilePatternMatch(relativePathWithSlashes) && (!this.includePattern || this.includePattern(relativePathWithSlashes))) {
|
||||
private matchFile(onResult: (result: IRawFileMatch) => void, base: string, path: string, size?: number): void {
|
||||
if (this.isFilePatternMatch(path) && (!this.includePattern || this.includePattern(path))) {
|
||||
this.resultCount++;
|
||||
|
||||
if (this.maxResults && this.resultCount > this.maxResults) {
|
||||
@@ -443,8 +476,8 @@ export class FileWalker {
|
||||
|
||||
if (!this.isLimitHit) {
|
||||
onResult({
|
||||
absolutePath,
|
||||
pathLabel: relativePathWithSlashes,
|
||||
base,
|
||||
path,
|
||||
size
|
||||
});
|
||||
}
|
||||
|
||||
@@ -67,9 +67,9 @@ export class SearchService implements IRawSearchService {
|
||||
searchPromise = this.doSearch(engine, batchSize)
|
||||
.then(c, e, progress => {
|
||||
if (Array.isArray(progress)) {
|
||||
p(progress.map(m => ({ path: m.absolutePath })));
|
||||
} else if ((<IRawFileMatch>progress).absolutePath) {
|
||||
p({ path: (<IRawFileMatch>progress).absolutePath });
|
||||
p(progress.map(m => this.rawMatchToSearchItem(m)));
|
||||
} else if ((<IRawFileMatch>progress).path) {
|
||||
p(this.rawMatchToSearchItem(<IRawFileMatch>progress));
|
||||
} else {
|
||||
p(progress);
|
||||
}
|
||||
@@ -77,6 +77,10 @@ export class SearchService implements IRawSearchService {
|
||||
}, () => searchPromise.cancel());
|
||||
}
|
||||
|
||||
private rawMatchToSearchItem(match: IRawFileMatch): ISerializedFileMatch {
|
||||
return { path: match.base ? [match.base, match.path].join(paths.nativeSep) : match.path };
|
||||
}
|
||||
|
||||
private doSortedSearch(engine: ISearchEngine<IRawFileMatch>, config: IRawSearch, batchSize?: number): PPromise<ISerializedSearchComplete, IRawProgressItem<IRawFileMatch>> {
|
||||
let searchPromise;
|
||||
return new PPromise<ISerializedSearchComplete, ISerializedSearchProgressItem>((c, e, p) => {
|
||||
@@ -178,7 +182,7 @@ export class SearchService implements IRawSearchService {
|
||||
const normalizedSearchValue = strings.stripWildcards(filePattern).toLowerCase();
|
||||
const compare = (elementA: IRawFileMatch, elementB: IRawFileMatch) => compareByScore(elementA, elementB, FileMatchAccessor, filePattern, normalizedSearchValue, cache.scorerCache);
|
||||
const filteredWrappers = arrays.top(results, compare, config.maxResults);
|
||||
return filteredWrappers.map(result => ({ path: result.absolutePath }));
|
||||
return filteredWrappers.map(result => this.rawMatchToSearchItem(result));
|
||||
}
|
||||
|
||||
private sendProgress(results: ISerializedFileMatch[], progressCb: (batch: ISerializedFileMatch[]) => void, batchSize?: number) {
|
||||
@@ -218,13 +222,12 @@ export class SearchService implements IRawSearchService {
|
||||
|
||||
// Pattern match on results and adjust highlights
|
||||
let results: IRawFileMatch[] = [];
|
||||
const normalizedSearchValue = searchValue.replace(/\\/g, '/'); // Normalize file patterns to forward slashes
|
||||
const normalizedSearchValueLowercase = strings.stripWildcards(normalizedSearchValue).toLowerCase();
|
||||
const normalizedSearchValueLowercase = strings.stripWildcards(searchValue).toLowerCase();
|
||||
for (let i = 0; i < cachedEntries.length; i++) {
|
||||
let entry = cachedEntries[i];
|
||||
|
||||
// Check if this entry is a match for the search value
|
||||
if (!scorer.matches(entry.pathLabel, normalizedSearchValueLowercase)) {
|
||||
if (!scorer.matches(entry.path, normalizedSearchValueLowercase)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -285,12 +288,12 @@ class FileMatchAccessor {
|
||||
|
||||
public static getLabel(match: IFileMatch): string {
|
||||
if (!match.label) {
|
||||
match.label = paths.basename(match.absolutePath);
|
||||
match.label = paths.basename(match.path);
|
||||
}
|
||||
return match.label;
|
||||
}
|
||||
|
||||
public static getResourcePath(match: IFileMatch): string {
|
||||
return match.absolutePath;
|
||||
return match.path;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +30,9 @@ export interface IRawSearchService {
|
||||
}
|
||||
|
||||
export interface IRawFileMatch {
|
||||
absolutePath: string;
|
||||
pathLabel: string;
|
||||
size: number;
|
||||
base?: string;
|
||||
path: string;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
export interface ISearchEngine<T> {
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import strings = require('vs/base/common/strings');
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
|
||||
import fs = require('fs');
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
import baseMime = require('vs/base/common/mime');
|
||||
import * as baseMime from 'vs/base/common/mime';
|
||||
import {ILineMatch, IProgress} from 'vs/platform/search/common/search';
|
||||
import {detectMimeAndEncodingFromBuffer} from 'vs/base/node/mime';
|
||||
import {FileWalker} from 'vs/workbench/services/search/node/fileSearch';
|
||||
@@ -110,6 +111,7 @@ export class Engine implements ISearchEngine<ISerializedFileMatch> {
|
||||
return unwind(size);
|
||||
};
|
||||
|
||||
const absolutePath = result.base ? [result.base, result.path].join(path.sep) : result.path;
|
||||
let perLineCallback = (line: string, lineNumber: number) => {
|
||||
if (this.limitReached || this.isCanceled) {
|
||||
return; // return early if canceled or limit reached
|
||||
@@ -126,7 +128,7 @@ export class Engine implements ISearchEngine<ISerializedFileMatch> {
|
||||
}
|
||||
|
||||
if (fileMatch === null) {
|
||||
fileMatch = new FileMatch(result.absolutePath);
|
||||
fileMatch = new FileMatch(absolutePath);
|
||||
}
|
||||
|
||||
if (lineMatch === null) {
|
||||
@@ -141,7 +143,7 @@ export class Engine implements ISearchEngine<ISerializedFileMatch> {
|
||||
};
|
||||
|
||||
// Read lines buffered to support large files
|
||||
this.readlinesAsync(result.absolutePath, perLineCallback, { bufferLength: 8096, encoding: this.fileEncoding }, doneCallback);
|
||||
this.readlinesAsync(absolutePath, perLineCallback, { bufferLength: 8096, encoding: this.fileEncoding }, doneCallback);
|
||||
}, (error, isLimitHit) => {
|
||||
this.walkerIsDone = true;
|
||||
this.walkerError = error;
|
||||
|
||||
@@ -159,7 +159,7 @@ suite('Search', () => {
|
||||
}, () => { }, (error) => {
|
||||
assert.ok(!error);
|
||||
assert.equal(count, 1);
|
||||
assert.strictEqual(path.basename(res.absolutePath), 'site.less');
|
||||
assert.strictEqual(path.basename(res.path), 'site.less');
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -256,7 +256,7 @@ suite('Search', () => {
|
||||
}, () => { }, (error) => {
|
||||
assert.ok(!error);
|
||||
assert.equal(count, 1);
|
||||
assert.equal(path.basename(res.absolutePath), '汉语.txt');
|
||||
assert.equal(path.basename(res.path), '汉语.txt');
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -296,7 +296,7 @@ suite('Search', () => {
|
||||
}, () => { }, (error) => {
|
||||
assert.ok(!error);
|
||||
assert.equal(count, 1);
|
||||
assert.equal(path.basename(res.absolutePath), 'site.css');
|
||||
assert.equal(path.basename(res.path), 'site.css');
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -317,7 +317,7 @@ suite('Search', () => {
|
||||
}, () => { }, (error) => {
|
||||
assert.ok(!error);
|
||||
assert.equal(count, 1);
|
||||
assert.equal(path.basename(res.absolutePath), 'company.js');
|
||||
assert.equal(path.basename(res.path), 'company.js');
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -339,7 +339,7 @@ suite('Search', () => {
|
||||
}, () => { }, (error) => {
|
||||
assert.ok(!error);
|
||||
assert.equal(count, 1);
|
||||
assert.equal(path.basename(res.absolutePath), 'company.js');
|
||||
assert.equal(path.basename(res.path), 'company.js');
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -365,7 +365,7 @@ suite('Search', () => {
|
||||
}, () => { }, (error) => {
|
||||
assert.ok(!error);
|
||||
assert.equal(count, 1);
|
||||
assert.equal(path.basename(res.absolutePath), 'company.js');
|
||||
assert.equal(path.basename(res.path), 'company.js');
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -392,7 +392,7 @@ suite('Search', () => {
|
||||
}, () => { }, (error) => {
|
||||
assert.ok(!error);
|
||||
assert.equal(count, 1);
|
||||
assert.equal(path.basename(res.absolutePath), 'site.css');
|
||||
assert.equal(path.basename(res.path), 'site.css');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import assert = require('assert');
|
||||
import * as assert from 'assert';
|
||||
import {normalize} from 'path';
|
||||
|
||||
import {IProgress, IUncachedSearchStats} from 'vs/platform/search/common/search';
|
||||
import {ISearchEngine, IRawSearch, IRawFileMatch, ISerializedFileMatch, ISerializedSearchComplete} from 'vs/workbench/services/search/node/search';
|
||||
@@ -67,18 +68,18 @@ class TestSearchEngine implements ISearchEngine<IRawFileMatch> {
|
||||
suite('SearchService', () => {
|
||||
|
||||
const rawSearch: IRawSearch = {
|
||||
rootFolders: ['/some/where'],
|
||||
rootFolders: [normalize('/some/where')],
|
||||
filePattern: 'a'
|
||||
};
|
||||
|
||||
const rawMatch: IRawFileMatch = {
|
||||
absolutePath: '/some/where',
|
||||
pathLabel: 'where',
|
||||
base: normalize('/some'),
|
||||
path: 'where',
|
||||
size: 123
|
||||
};
|
||||
|
||||
const match: ISerializedFileMatch = {
|
||||
path: '/some/where'
|
||||
path: normalize('/some/where')
|
||||
};
|
||||
|
||||
test('Individual results', function () {
|
||||
@@ -122,7 +123,7 @@ suite('SearchService', () => {
|
||||
});
|
||||
|
||||
test('Collect batched results', function () {
|
||||
const path = '/some/where';
|
||||
const uriPath = '/some/where';
|
||||
let i = 25;
|
||||
const Engine = TestSearchEngine.bind(null, () => i-- && rawMatch);
|
||||
const service = new RawSearchService();
|
||||
@@ -134,16 +135,16 @@ suite('SearchService', () => {
|
||||
assert.strictEqual(result.results.length, 25, 'Result');
|
||||
assert.strictEqual(progressResults.length, 25, 'Progress');
|
||||
}, null, match => {
|
||||
assert.strictEqual(match.resource.path, path);
|
||||
assert.strictEqual(match.resource.path, uriPath);
|
||||
progressResults.push(match);
|
||||
});
|
||||
});
|
||||
|
||||
test('Sorted results', function () {
|
||||
const paths = ['bab', 'bbc', 'abb'];
|
||||
const matches = paths.map(path => ({
|
||||
absolutePath: `/some/where/${path}`,
|
||||
pathLabel: path,
|
||||
const matches: IRawFileMatch[] = paths.map(path => ({
|
||||
base: normalize('/some/where'),
|
||||
path,
|
||||
size: 3
|
||||
}));
|
||||
let i = 0;
|
||||
@@ -152,13 +153,13 @@ suite('SearchService', () => {
|
||||
|
||||
const results = [];
|
||||
return service.doFileSearch(Engine, {
|
||||
rootFolders: ['/some/where'],
|
||||
rootFolders: [normalize('/some/where')],
|
||||
filePattern: 'bb',
|
||||
sortByScore: true,
|
||||
maxResults: 2
|
||||
}, 1).then(() => {
|
||||
assert.notStrictEqual(typeof TestSearchEngine.last.config.maxResults, 'number');
|
||||
assert.deepStrictEqual(results, ['/some/where/bbc', '/some/where/bab']);
|
||||
assert.deepStrictEqual(results, [normalize('/some/where/bbc'), normalize('/some/where/bab')]);
|
||||
}, null, value => {
|
||||
if (Array.isArray(value)) {
|
||||
results.push(...value.map(v => v.path));
|
||||
@@ -175,7 +176,7 @@ suite('SearchService', () => {
|
||||
|
||||
const results = [];
|
||||
return service.doFileSearch(Engine, {
|
||||
rootFolders: ['/some/where'],
|
||||
rootFolders: [normalize('/some/where')],
|
||||
filePattern: 'a',
|
||||
sortByScore: true,
|
||||
maxResults: 23
|
||||
@@ -196,9 +197,9 @@ suite('SearchService', () => {
|
||||
|
||||
test('Cached results', function () {
|
||||
const paths = ['bcb', 'bbc', 'aab'];
|
||||
const matches = paths.map(path => ({
|
||||
absolutePath: `/some/where/${path}`,
|
||||
pathLabel: path,
|
||||
const matches: IRawFileMatch[] = paths.map(path => ({
|
||||
base: normalize('/some/where'),
|
||||
path,
|
||||
size: 3
|
||||
}));
|
||||
let i = 0;
|
||||
@@ -207,13 +208,13 @@ suite('SearchService', () => {
|
||||
|
||||
const results = [];
|
||||
return service.doFileSearch(Engine, {
|
||||
rootFolders: ['/some/where'],
|
||||
rootFolders: [normalize('/some/where')],
|
||||
filePattern: 'b',
|
||||
sortByScore: true,
|
||||
cacheKey: 'x'
|
||||
}, -1).then(complete => {
|
||||
assert.strictEqual(complete.stats.fromCache, false);
|
||||
assert.deepStrictEqual(results, ['/some/where/bcb', '/some/where/bbc', '/some/where/aab']);
|
||||
assert.deepStrictEqual(results, [normalize('/some/where/bcb'), normalize('/some/where/bbc'), normalize('/some/where/aab')]);
|
||||
}, null, value => {
|
||||
if (Array.isArray(value)) {
|
||||
results.push(...value.map(v => v.path));
|
||||
@@ -223,13 +224,13 @@ suite('SearchService', () => {
|
||||
}).then(() => {
|
||||
const results = [];
|
||||
return service.doFileSearch(Engine, {
|
||||
rootFolders: ['/some/where'],
|
||||
rootFolders: [normalize('/some/where')],
|
||||
filePattern: 'bc',
|
||||
sortByScore: true,
|
||||
cacheKey: 'x'
|
||||
}, -1).then(complete => {
|
||||
assert.ok(complete.stats.fromCache);
|
||||
assert.deepStrictEqual(results, ['/some/where/bcb', '/some/where/bbc']);
|
||||
assert.deepStrictEqual(results, [normalize('/some/where/bcb'), normalize('/some/where/bbc')]);
|
||||
}, null, value => {
|
||||
if (Array.isArray(value)) {
|
||||
results.push(...value.map(v => v.path));
|
||||
@@ -241,19 +242,19 @@ suite('SearchService', () => {
|
||||
return service.clearCache('x');
|
||||
}).then(() => {
|
||||
matches.push({
|
||||
absolutePath: '/some/where/bc',
|
||||
pathLabel: 'bc',
|
||||
base: normalize('/some/where'),
|
||||
path: 'bc',
|
||||
size: 3
|
||||
});
|
||||
const results = [];
|
||||
return service.doFileSearch(Engine, {
|
||||
rootFolders: ['/some/where'],
|
||||
rootFolders: [normalize('/some/where')],
|
||||
filePattern: 'bc',
|
||||
sortByScore: true,
|
||||
cacheKey: 'x'
|
||||
}, -1).then(complete => {
|
||||
assert.strictEqual(complete.stats.fromCache, false);
|
||||
assert.deepStrictEqual(results, ['/some/where/bc']);
|
||||
assert.deepStrictEqual(results, [normalize('/some/where/bc')]);
|
||||
}, null, value => {
|
||||
if (Array.isArray(value)) {
|
||||
results.push(...value.map(v => v.path));
|
||||
|
||||
Reference in New Issue
Block a user