mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-12 02:58:31 -05:00
Merge from master
This commit is contained in:
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user