提交 a7190d61 编写于 作者: C Christof Marti

Use 'dir' on Windows

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