Skip to content

Commit 51ec5e9

Browse files
author
Benjamin Pasero
committed
quick access - picker tests
1 parent a8e13f1 commit 51ec5e9

3 files changed

Lines changed: 130 additions & 4 deletions

File tree

src/vs/platform/quickinput/browser/pickerQuickAccess.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,22 @@ export abstract class PickerQuickAccessProvider<T extends IPickerQuickAccessItem
9595
const picksToken = picksCts.token;
9696
const res = this.getPicks(picker.value.substr(this.prefix.length).trim(), disposables.add(new DisposableStore()), picksToken);
9797
if (isFastAndSlowPicksType(res)) {
98-
picker.items = res.picks;
98+
if (res.picks.length > 0) {
99+
// Optimization: if there are no fast results
100+
// we do nto simply unset all the existing items
101+
// to reduce the flickering.
102+
picker.items = res.picks;
103+
}
99104
picker.busy = true;
100105
try {
101106
const additionalPicks = await res.additionalPicks;
102107
if (picksToken.isCancellationRequested) {
103108
return;
104109
}
105110

106-
if (additionalPicks.length > 0) {
111+
if (res.picks.length === 0 || additionalPicks.length > 0) {
112+
// Optimization: we only update the picker items if we either
113+
// did not update them earlier, or we actually got new results
107114
picker.items = [...res.picks, ...additionalPicks];
108115
}
109116
} finally {
@@ -187,5 +194,5 @@ export abstract class PickerQuickAccessProvider<T extends IPickerQuickAccessItem
187194
* through this token.
188195
* @returns the picks either directly, as promise or combined fast and slow results.
189196
*/
190-
protected abstract getPicks(filter: string, disposables: DisposableStore, token: CancellationToken): Array<T | IQuickPickSeparator> | Promise<Array<T | IQuickPickSeparator>> | { picks: Array<T | IQuickPickSeparator>, additionalPicks: Promise<Array<T | IQuickPickSeparator>> };
197+
protected abstract getPicks(filter: string, disposables: DisposableStore, token: CancellationToken): Array<T | IQuickPickSeparator> | Promise<Array<T | IQuickPickSeparator>> | FastAndSlowPicksType<T>;
191198
}

src/vs/workbench/contrib/search/browser/anythingQuickAccess.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
105105
return super.provide(picker, token);
106106
}
107107

108-
protected getPicks(filter: string, disposables: DisposableStore, token: CancellationToken): FastAndSlowPicksType<IAnythingQuickPickItem | IQuickPickSeparator> {
108+
protected getPicks(filter: string, disposables: DisposableStore, token: CancellationToken): FastAndSlowPicksType<IAnythingQuickPickItem> {
109109

110110
// Find a suitable range from the pattern looking for ":", "#" or ","
111111
let range: IRange | undefined = undefined;

src/vs/workbench/test/browser/quickAccess.test.ts

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
1212
import { TestServiceAccessor, workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
1313
import { DisposableStore, toDisposable, IDisposable } from 'vs/base/common/lifecycle';
1414
import { timeout } from 'vs/base/common/async';
15+
import { PickerQuickAccessProvider, FastAndSlowPicksType } from 'vs/platform/quickinput/browser/pickerQuickAccess';
1516

1617
suite('QuickAccess', () => {
1718

@@ -192,4 +193,122 @@ suite('QuickAccess', () => {
192193

193194
restore();
194195
});
196+
197+
let fastProviderCalled = false;
198+
let slowProviderCalled = false;
199+
let fastAndSlowProviderCalled = false;
200+
201+
let slowProviderCanceled = false;
202+
let fastAndSlowProviderCanceled = false;
203+
204+
class FastTestQuickPickProvider extends PickerQuickAccessProvider<IQuickPickItem> {
205+
206+
constructor() {
207+
super('fast');
208+
}
209+
210+
protected getPicks(filter: string, disposables: DisposableStore, token: CancellationToken): Array<IQuickPickItem> {
211+
fastProviderCalled = true;
212+
213+
return [{ label: 'Fast Pick' }];
214+
}
215+
}
216+
217+
class SlowTestQuickPickProvider extends PickerQuickAccessProvider<IQuickPickItem> {
218+
219+
constructor() {
220+
super('slow');
221+
}
222+
223+
protected async getPicks(filter: string, disposables: DisposableStore, token: CancellationToken): Promise<Array<IQuickPickItem>> {
224+
slowProviderCalled = true;
225+
226+
await timeout(1);
227+
228+
if (token.isCancellationRequested) {
229+
slowProviderCanceled = true;
230+
}
231+
232+
return [{ label: 'Slow Pick' }];
233+
}
234+
}
235+
236+
class FastAndSlowTestQuickPickProvider extends PickerQuickAccessProvider<IQuickPickItem> {
237+
238+
constructor() {
239+
super('bothFastAndSlow');
240+
}
241+
242+
protected getPicks(filter: string, disposables: DisposableStore, token: CancellationToken): FastAndSlowPicksType<IQuickPickItem> {
243+
fastAndSlowProviderCalled = true;
244+
245+
return {
246+
picks: [{ label: 'Fast Pick' }],
247+
additionalPicks: (async () => {
248+
await timeout(1);
249+
250+
if (token.isCancellationRequested) {
251+
fastAndSlowProviderCanceled = true;
252+
}
253+
254+
return [{ label: 'Slow Pick' }];
255+
})()
256+
};
257+
}
258+
}
259+
260+
const fastProviderDescriptor = { ctor: FastTestQuickPickProvider, prefix: 'fast', helpEntries: [] };
261+
const slowProviderDescriptor = { ctor: SlowTestQuickPickProvider, prefix: 'slow', helpEntries: [] };
262+
const fastAndSlowProviderDescriptor = { ctor: FastAndSlowTestQuickPickProvider, prefix: 'bothFastAndSlow', helpEntries: [] };
263+
264+
test('quick pick access', async () => {
265+
const registry = (Registry.as<IQuickAccessRegistry>(Extensions.Quickaccess));
266+
const restore = (registry as QuickAccessRegistry).clear();
267+
268+
const disposables = new DisposableStore();
269+
270+
disposables.add(registry.registerQuickAccessProvider(fastProviderDescriptor));
271+
disposables.add(registry.registerQuickAccessProvider(slowProviderDescriptor));
272+
disposables.add(registry.registerQuickAccessProvider(fastAndSlowProviderDescriptor));
273+
274+
accessor.quickInputService.quickAccess.show('fast');
275+
assert.equal(fastProviderCalled, true);
276+
assert.equal(slowProviderCalled, false);
277+
assert.equal(fastAndSlowProviderCalled, false);
278+
fastProviderCalled = false;
279+
280+
accessor.quickInputService.quickAccess.show('slow');
281+
await timeout(2);
282+
283+
assert.equal(fastProviderCalled, false);
284+
assert.equal(slowProviderCalled, true);
285+
assert.equal(slowProviderCanceled, false);
286+
assert.equal(fastAndSlowProviderCalled, false);
287+
slowProviderCalled = false;
288+
289+
accessor.quickInputService.quickAccess.show('bothFastAndSlow');
290+
await timeout(2);
291+
292+
assert.equal(fastProviderCalled, false);
293+
assert.equal(slowProviderCalled, false);
294+
assert.equal(fastAndSlowProviderCalled, true);
295+
assert.equal(fastAndSlowProviderCanceled, false);
296+
fastAndSlowProviderCalled = false;
297+
298+
accessor.quickInputService.quickAccess.show('slow');
299+
accessor.quickInputService.quickAccess.show('bothFastAndSlow');
300+
accessor.quickInputService.quickAccess.show('fast');
301+
302+
assert.equal(fastProviderCalled, true);
303+
assert.equal(slowProviderCalled, true);
304+
assert.equal(fastAndSlowProviderCalled, true);
305+
306+
await timeout(2);
307+
assert.equal(slowProviderCanceled, true);
308+
assert.equal(fastAndSlowProviderCanceled, true);
309+
310+
disposables.dispose();
311+
312+
restore();
313+
});
195314
});

0 commit comments

Comments
 (0)