Merge from master

This commit is contained in:
Raj Musuku
2019-02-21 17:56:04 -08:00
parent 5a146e34fa
commit 666ae11639
11482 changed files with 119352 additions and 255574 deletions

View File

@@ -2,20 +2,22 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { mapArrayOrNot } from 'vs/base/common/arrays';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { isPromiseCanceledError } from 'vs/base/common/errors';
import { dispose } from 'vs/base/common/lifecycle';
import { joinPath } from 'vs/base/common/resources';
import URI, { UriComponents } from 'vs/base/common/uri';
import { TPromise } from 'vs/base/common/winjs.base';
import { URI, UriComponents } from 'vs/base/common/uri';
import * as extfs from 'vs/base/node/extfs';
import { IFileMatch, IPatternInfo, IRawFileMatch2, IRawSearchQuery, ISearchCompleteStats, ISearchQuery, QueryType } from 'vs/platform/search/common/search';
import { IFileMatch, IFileQuery, IPatternInfo, IRawFileMatch2, ISearchCompleteStats, ISearchQuery, ITextQuery, QueryType, resultIsMatch } from 'vs/platform/search/common/search';
import { MainContext, MainThreadSearchShape } from 'vs/workbench/api/node/extHost.protocol';
import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration';
import { ExtHostSearch } from 'vs/workbench/api/node/extHostSearch';
import { Range } from 'vs/workbench/api/node/extHostTypes';
import { extensionResultIsMatch } from 'vs/workbench/services/search/node/textSearchManager';
import { TestRPCProtocol } from 'vs/workbench/test/electron-browser/api/testRPCProtocol';
import { TestLogService } from 'vs/workbench/test/workbenchTestServices';
import * as vscode from 'vscode';
let rpcProtocol: TestRPCProtocol;
@@ -58,6 +60,12 @@ class MockMainThreadSearch implements MainThreadSearchShape {
}
}
class MockExtHostConfiguration {
getConfiguration(section?: string, resource?: URI, extensionId?: string): vscode.WorkspaceConfiguration {
return <vscode.WorkspaceConfiguration>{};
}
}
let mockExtfs: Partial<typeof extfs>;
suite('ExtHostSearch', () => {
@@ -71,13 +79,14 @@ suite('ExtHostSearch', () => {
await rpcProtocol.sync();
}
async function runFileSearch(query: IRawSearchQuery, cancel = false): Promise<{ results: URI[]; stats: ISearchCompleteStats }> {
async function runFileSearch(query: IFileQuery, cancel = false): Promise<{ results: URI[]; stats: ISearchCompleteStats }> {
let stats: ISearchCompleteStats;
try {
const p = extHostSearch.$provideFileSearchResults(mockMainThreadSearch.lastHandle, 0, query);
const cancellation = new CancellationTokenSource();
const p = extHostSearch.$provideFileSearchResults(mockMainThreadSearch.lastHandle, 0, query, cancellation.token);
if (cancel) {
await new TPromise(resolve => process.nextTick(resolve));
p.cancel();
await new Promise(resolve => process.nextTick(resolve));
cancellation.cancel();
}
stats = await p;
@@ -95,13 +104,14 @@ suite('ExtHostSearch', () => {
};
}
async function runTextSearch(pattern: IPatternInfo, query: IRawSearchQuery, cancel = false): Promise<{ results: IFileMatch[], stats: ISearchCompleteStats }> {
async function runTextSearch(query: ITextQuery, cancel = false): Promise<{ results: IFileMatch[], stats: ISearchCompleteStats }> {
let stats: ISearchCompleteStats;
try {
const p = extHostSearch.$provideTextSearchResults(mockMainThreadSearch.lastHandle, 0, pattern, query);
const cancellation = new CancellationTokenSource();
const p = extHostSearch.$provideTextSearchResults(mockMainThreadSearch.lastHandle, 0, query, cancellation.token);
if (cancel) {
await new TPromise(resolve => process.nextTick(resolve));
p.cancel();
await new Promise(resolve => process.nextTick(resolve));
cancellation.cancel();
}
stats = await p;
@@ -127,11 +137,13 @@ suite('ExtHostSearch', () => {
rpcProtocol = new TestRPCProtocol();
mockMainThreadSearch = new MockMainThreadSearch();
const logService = new TestLogService();
const ehConfiguration: ExtHostConfiguration = new MockExtHostConfiguration() as any;
rpcProtocol.set(MainContext.MainThreadSearch, mockMainThreadSearch);
mockExtfs = {};
extHostSearch = new ExtHostSearch(rpcProtocol, null, mockExtfs as typeof extfs);
extHostSearch = new ExtHostSearch(rpcProtocol, null, logService, ehConfiguration, mockExtfs as typeof extfs);
});
teardown(() => {
@@ -146,7 +158,7 @@ suite('ExtHostSearch', () => {
suite('File:', () => {
function getSimpleQuery(filePattern = ''): ISearchQuery {
function getSimpleQuery(filePattern = ''): IFileQuery {
return {
type: QueryType.File,
@@ -168,7 +180,7 @@ suite('ExtHostSearch', () => {
test('no results', async () => {
await registerTestFileSearchProvider({
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
return TPromise.wrap(null);
return Promise.resolve(null);
}
});
@@ -186,7 +198,7 @@ suite('ExtHostSearch', () => {
await registerTestFileSearchProvider({
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
return TPromise.wrap(reportedResults);
return Promise.resolve(reportedResults);
}
});
@@ -200,7 +212,7 @@ suite('ExtHostSearch', () => {
let cancelRequested = false;
await registerTestFileSearchProvider({
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
return new TPromise((resolve, reject) => {
return new Promise((resolve, reject) => {
token.onCancellationRequested(() => {
cancelRequested = true;
@@ -234,7 +246,7 @@ suite('ExtHostSearch', () => {
await registerTestFileSearchProvider({
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
assert(options.excludes.length === 2 && options.includes.length === 2, 'Missing global include/excludes');
return TPromise.wrap(null);
return Promise.resolve(null);
}
});
@@ -270,7 +282,7 @@ suite('ExtHostSearch', () => {
assert.deepEqual(options.excludes.sort(), ['*.js']);
}
return TPromise.wrap(null);
return Promise.resolve(null);
}
});
@@ -307,7 +319,7 @@ suite('ExtHostSearch', () => {
assert.deepEqual(options.includes.sort(), ['*.jsx', '*.ts']);
assert.deepEqual(options.excludes.sort(), []);
return TPromise.wrap(null);
return Promise.resolve(null);
}
});
@@ -347,7 +359,7 @@ suite('ExtHostSearch', () => {
await registerTestFileSearchProvider({
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
return TPromise.wrap(reportedResults
return Promise.resolve(reportedResults
.map(relativePath => joinPath(options.folder, relativePath)));
}
});
@@ -393,7 +405,7 @@ suite('ExtHostSearch', () => {
].map(relativePath => joinPath(rootFolderB, relativePath));
}
return TPromise.wrap(reportedResults);
return Promise.resolve(reportedResults);
}
});
@@ -450,7 +462,7 @@ suite('ExtHostSearch', () => {
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
token.onCancellationRequested(() => wasCanceled = true);
return TPromise.wrap(reportedResults);
return Promise.resolve(reportedResults);
}
});
@@ -486,7 +498,7 @@ suite('ExtHostSearch', () => {
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
token.onCancellationRequested(() => wasCanceled = true);
return TPromise.wrap(reportedResults);
return Promise.resolve(reportedResults);
}
});
@@ -521,7 +533,7 @@ suite('ExtHostSearch', () => {
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
token.onCancellationRequested(() => wasCanceled = true);
return TPromise.wrap(reportedResults);
return Promise.resolve(reportedResults);
}
});
@@ -548,18 +560,16 @@ suite('ExtHostSearch', () => {
test('multiroot max results', async () => {
let cancels = 0;
await registerTestFileSearchProvider({
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
async provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Promise<URI[]> {
token.onCancellationRequested(() => cancels++);
// Provice results async so it has a chance to invoke every provider
return new TPromise(r => process.nextTick(r))
.then(() => {
return [
'file1.ts',
'file2.ts',
'file3.ts',
].map(relativePath => joinPath(options.folder, relativePath));
});
await new Promise(r => process.nextTick(r));
return [
'file1.ts',
'file2.ts',
'file3.ts',
].map(relativePath => joinPath(options.folder, relativePath));
}
});
@@ -594,7 +604,7 @@ suite('ExtHostSearch', () => {
await registerTestFileSearchProvider({
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
return TPromise.wrap(reportedResults);
return Promise.resolve(reportedResults);
}
}, fancyScheme);
@@ -615,24 +625,25 @@ suite('ExtHostSearch', () => {
suite('Text:', () => {
function makePreview(text: string): vscode.TextSearchResult['preview'] {
function makePreview(text: string): vscode.TextSearchMatch['preview'] {
return {
match: new Range(0, 0, 0, text.length),
matches: new Range(0, 0, 0, text.length),
text
};
}
function makeTextResult(baseFolder: URI, relativePath: string): vscode.TextSearchResult {
function makeTextResult(baseFolder: URI, relativePath: string): vscode.TextSearchMatch {
return {
preview: makePreview('foo'),
range: new Range(0, 0, 0, 3),
ranges: new Range(0, 0, 0, 3),
uri: joinPath(baseFolder, relativePath)
};
}
function getSimpleQuery(): ISearchQuery {
function getSimpleQuery(queryText: string): ITextQuery {
return {
type: QueryType.Text,
contentPattern: getPattern(queryText),
folderQueries: [
{ folder: rootFolderA }
@@ -650,11 +661,25 @@ suite('ExtHostSearch', () => {
const actualTextSearchResults: vscode.TextSearchResult[] = [];
for (let fileMatch of actual) {
// Make relative
for (let lineMatch of fileMatch.lineMatches) {
for (let [offset, length] of lineMatch.offsetAndLengths) {
for (let lineResult of fileMatch.results) {
if (resultIsMatch(lineResult)) {
actualTextSearchResults.push({
preview: { text: lineMatch.preview, match: null },
range: new Range(lineMatch.lineNumber, offset, lineMatch.lineNumber, length + offset),
preview: {
text: lineResult.preview.text,
matches: mapArrayOrNot(
lineResult.preview.matches,
m => new Range(m.startLineNumber, m.startColumn, m.endLineNumber, m.endColumn))
},
ranges: mapArrayOrNot(
lineResult.ranges,
r => new Range(r.startLineNumber, r.startColumn, r.endLineNumber, r.endColumn),
),
uri: fileMatch.resource
});
} else {
actualTextSearchResults.push(<vscode.TextSearchContext>{
text: lineResult.text,
lineNumber: lineResult.lineNumber,
uri: fileMatch.resource
});
}
@@ -664,18 +689,23 @@ suite('ExtHostSearch', () => {
const rangeToString = (r: vscode.Range) => `(${r.start.line}, ${r.start.character}), (${r.end.line}, ${r.end.character})`;
const makeComparable = (results: vscode.TextSearchResult[]) => results
.sort((a, b) => b.preview.text.localeCompare(a.preview.text))
.map(r => ({
...r,
...{
uri: r.uri.toString(),
range: rangeToString(r.range),
preview: {
text: r.preview.text,
match: null // Don't care about this right now
}
.sort((a, b) => {
const compareKeyA = a.uri.toString() + ': ' + (extensionResultIsMatch(a) ? a.preview.text : a.text);
const compareKeyB = b.uri.toString() + ': ' + (extensionResultIsMatch(b) ? b.preview.text : b.text);
return compareKeyB.localeCompare(compareKeyA);
})
.map(r => extensionResultIsMatch(r) ? {
uri: r.uri.toString(),
range: mapArrayOrNot(r.ranges, rangeToString),
preview: {
text: r.preview.text,
match: null // Don't care about this right now
}
}));
} : {
uri: r.uri.toString(),
text: r.text,
lineNumber: r.lineNumber
});
return assert.deepEqual(
makeComparable(actualTextSearchResults),
@@ -684,12 +714,12 @@ suite('ExtHostSearch', () => {
test('no results', async () => {
await registerTestTextSearchProvider({
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
return TPromise.wrap(null);
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
return Promise.resolve(null);
}
});
const { results, stats } = await runTextSearch(getPattern('foo'), getSimpleQuery());
const { results, stats } = await runTextSearch(getSimpleQuery('foo'));
assert(!stats.limitHit);
assert(!results.length);
});
@@ -701,28 +731,29 @@ suite('ExtHostSearch', () => {
];
await registerTestTextSearchProvider({
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
providedResults.forEach(r => progress.report(r));
return TPromise.wrap(null);
return Promise.resolve(null);
}
});
const { results, stats } = await runTextSearch(getPattern('foo'), getSimpleQuery());
const { results, stats } = await runTextSearch(getSimpleQuery('foo'));
assert(!stats.limitHit);
assertResults(results, providedResults);
});
test('all provider calls get global include/excludes', async () => {
await registerTestTextSearchProvider({
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
assert.equal(options.includes.length, 1);
assert.equal(options.excludes.length, 1);
return TPromise.wrap(null);
return Promise.resolve(null);
}
});
const query: IRawSearchQuery = {
const query: ITextQuery = {
type: QueryType.Text,
contentPattern: getPattern('foo'),
includePattern: {
'*.ts': true
@@ -738,12 +769,12 @@ suite('ExtHostSearch', () => {
]
};
await runTextSearch(getPattern('foo'), query);
await runTextSearch(query);
});
test('global/local include/excludes combined', async () => {
await registerTestTextSearchProvider({
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
if (options.folder.toString() === rootFolderA.toString()) {
assert.deepEqual(options.includes.sort(), ['*.ts', 'foo']);
assert.deepEqual(options.excludes.sort(), ['*.js', 'bar']);
@@ -752,12 +783,13 @@ suite('ExtHostSearch', () => {
assert.deepEqual(options.excludes.sort(), ['*.js']);
}
return TPromise.wrap(null);
return Promise.resolve(null);
}
});
const query: IRawSearchQuery = {
const query: ITextQuery = {
type: QueryType.Text,
contentPattern: getPattern('foo'),
includePattern: {
'*.ts': true
@@ -779,21 +811,22 @@ suite('ExtHostSearch', () => {
]
};
await runTextSearch(getPattern('foo'), query);
await runTextSearch(query);
});
test('include/excludes resolved correctly', async () => {
await registerTestTextSearchProvider({
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
assert.deepEqual(options.includes.sort(), ['*.jsx', '*.ts']);
assert.deepEqual(options.excludes.sort(), []);
return TPromise.wrap(null);
return Promise.resolve(null);
}
});
const query: ISearchQuery = {
type: QueryType.Text,
contentPattern: getPattern('foo'),
includePattern: {
'*.ts': true,
@@ -816,18 +849,18 @@ suite('ExtHostSearch', () => {
]
};
await runTextSearch(getPattern('foo'), query);
await runTextSearch(query);
});
test('provider fail', async () => {
await registerTestTextSearchProvider({
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
throw new Error('Provider fail');
}
});
try {
await runTextSearch(getPattern('foo'), getSimpleQuery());
await runTextSearch(getSimpleQuery('foo'));
assert(false, 'Expected to fail');
} catch {
// expected to fail
@@ -852,14 +885,15 @@ suite('ExtHostSearch', () => {
];
await registerTestTextSearchProvider({
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
providedResults.forEach(r => progress.report(r));
return TPromise.wrap(null);
return Promise.resolve(null);
}
});
const query: ISearchQuery = {
type: QueryType.Text,
contentPattern: getPattern('foo'),
excludePattern: {
'*.js': {
@@ -872,7 +906,7 @@ suite('ExtHostSearch', () => {
]
};
const { results } = await runTextSearch(getPattern('foo'), query);
const { results } = await runTextSearch(query);
assertResults(results, providedResults.slice(1));
});
@@ -896,7 +930,7 @@ suite('ExtHostSearch', () => {
};
await registerTestTextSearchProvider({
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
let reportedResults;
if (options.folder.fsPath === rootFolderA.fsPath) {
reportedResults = [
@@ -913,12 +947,13 @@ suite('ExtHostSearch', () => {
}
reportedResults.forEach(r => progress.report(r));
return TPromise.wrap(null);
return Promise.resolve(null);
}
});
const query: ISearchQuery = {
type: QueryType.Text,
contentPattern: getPattern('foo'),
excludePattern: {
'*.js': {
@@ -944,7 +979,7 @@ suite('ExtHostSearch', () => {
]
};
const { results } = await runTextSearch(getPattern('foo'), query);
const { results } = await runTextSearch(query);
assertResults(results, [
makeTextResult(rootFolderA, 'folder/fileA.scss'),
makeTextResult(rootFolderA, 'folder/file2.css'),
@@ -960,14 +995,15 @@ suite('ExtHostSearch', () => {
];
await registerTestTextSearchProvider({
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
providedResults.forEach(r => progress.report(r));
return TPromise.wrap(null);
return Promise.resolve(null);
}
});
const query: ISearchQuery = {
type: QueryType.Text,
contentPattern: getPattern('foo'),
includePattern: {
'*.ts': true
@@ -978,7 +1014,7 @@ suite('ExtHostSearch', () => {
]
};
const { results } = await runTextSearch(getPattern('foo'), query);
const { results } = await runTextSearch(query);
assertResults(results, providedResults.slice(1));
});
@@ -990,15 +1026,16 @@ suite('ExtHostSearch', () => {
let wasCanceled = false;
await registerTestTextSearchProvider({
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
token.onCancellationRequested(() => wasCanceled = true);
providedResults.forEach(r => progress.report(r));
return TPromise.wrap(null);
return Promise.resolve(null);
}
});
const query: ISearchQuery = {
type: QueryType.Text,
contentPattern: getPattern('foo'),
maxResults: 1,
@@ -1007,7 +1044,7 @@ suite('ExtHostSearch', () => {
]
};
const { results, stats } = await runTextSearch(getPattern('foo'), query);
const { results, stats } = await runTextSearch(query);
assert(stats.limitHit, 'Expected to return limitHit');
assertResults(results, providedResults.slice(0, 1));
assert(wasCanceled, 'Expected to be canceled');
@@ -1022,15 +1059,16 @@ suite('ExtHostSearch', () => {
let wasCanceled = false;
await registerTestTextSearchProvider({
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
token.onCancellationRequested(() => wasCanceled = true);
providedResults.forEach(r => progress.report(r));
return TPromise.wrap(null);
return Promise.resolve(null);
}
});
const query: ISearchQuery = {
type: QueryType.Text,
contentPattern: getPattern('foo'),
maxResults: 2,
@@ -1039,7 +1077,7 @@ suite('ExtHostSearch', () => {
]
};
const { results, stats } = await runTextSearch(getPattern('foo'), query);
const { results, stats } = await runTextSearch(query);
assert(stats.limitHit, 'Expected to return limitHit');
assertResults(results, providedResults.slice(0, 2));
assert(wasCanceled, 'Expected to be canceled');
@@ -1053,15 +1091,16 @@ suite('ExtHostSearch', () => {
let wasCanceled = false;
await registerTestTextSearchProvider({
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
token.onCancellationRequested(() => wasCanceled = true);
providedResults.forEach(r => progress.report(r));
return TPromise.wrap(null);
return Promise.resolve(null);
}
});
const query: ISearchQuery = {
type: QueryType.Text,
contentPattern: getPattern('foo'),
maxResults: 2,
@@ -1070,30 +1109,60 @@ suite('ExtHostSearch', () => {
]
};
const { results, stats } = await runTextSearch(getPattern('foo'), query);
const { results, stats } = await runTextSearch(query);
assert(!stats.limitHit, 'Expected not to return limitHit');
assertResults(results, providedResults);
assert(!wasCanceled, 'Expected not to be canceled');
});
test('multiroot max results', async () => {
let cancels = 0;
test('provider returns early with limitHit', async () => {
const providedResults: vscode.TextSearchResult[] = [
makeTextResult(rootFolderA, 'file1.ts'),
makeTextResult(rootFolderA, 'file2.ts'),
makeTextResult(rootFolderA, 'file3.ts')
];
await registerTestTextSearchProvider({
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
token.onCancellationRequested(() => cancels++);
return new TPromise(r => process.nextTick(r))
.then(() => {
[
'file1.ts',
'file2.ts',
'file3.ts',
].forEach(f => progress.report(makeTextResult(options.folder, f)));
});
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
providedResults.forEach(r => progress.report(r));
return Promise.resolve({ limitHit: true });
}
});
const query: ISearchQuery = {
type: QueryType.Text,
contentPattern: getPattern('foo'),
maxResults: 1000,
folderQueries: [
{ folder: rootFolderA }
]
};
const { results, stats } = await runTextSearch(query);
assert(stats.limitHit, 'Expected to return limitHit');
assertResults(results, providedResults);
});
test('multiroot max results', async () => {
let cancels = 0;
await registerTestTextSearchProvider({
async provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Promise<vscode.TextSearchComplete> {
token.onCancellationRequested(() => cancels++);
await new Promise(r => process.nextTick(r));
[
'file1.ts',
'file2.ts',
'file3.ts',
].forEach(f => progress.report(makeTextResult(options.folder, f)));
return null;
}
});
const query: ISearchQuery = {
type: QueryType.Text,
contentPattern: getPattern('foo'),
maxResults: 2,
@@ -1103,7 +1172,7 @@ suite('ExtHostSearch', () => {
]
};
const { results } = await runTextSearch(getPattern('foo'), query);
const { results } = await runTextSearch(query);
assert.equal(results.length, 2);
assert.equal(cancels, 2);
});
@@ -1116,21 +1185,22 @@ suite('ExtHostSearch', () => {
];
await registerTestTextSearchProvider({
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
providedResults.forEach(r => progress.report(r));
return TPromise.wrap(null);
return Promise.resolve(null);
}
}, fancyScheme);
const query: ISearchQuery = {
type: QueryType.Text,
contentPattern: getPattern('foo'),
folderQueries: [
{ folder: fancySchemeFolderA }
]
};
const { results } = await runTextSearch(getPattern('foo'), query);
const { results } = await runTextSearch(query);
assertResults(results, providedResults);
});
});