Skip to content

Commit dd0a21a

Browse files
committed
Add tests for sort order and selection
1 parent ec168c7 commit dd0a21a

2 files changed

Lines changed: 172 additions & 10 deletions

File tree

extensions/ql-vscode/src/query-history.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ const FAILED_QUERY_HISTORY_ITEM_ICON = 'media/red-x.svg';
7070
*/
7171
const LOCAL_SUCCESS_QUERY_HISTORY_ITEM_ICON = 'media/drive.svg';
7272

73-
enum SortOrder {
73+
export enum SortOrder {
7474
NameAsc = 'NameAsc',
7575
NameDesc = 'NameDesc',
7676
DateAsc = 'DateAsc',
@@ -820,6 +820,9 @@ the file in the file explorer and dragging it into the workspace.`
820820

821821
/**
822822
* If no items are selected, attempt to grab the selection from the treeview.
823+
* However, often the treeview itself does not have any selection. In this case,
824+
* grab the selection from the `treeDataProvider` current item.
825+
*
823826
* We need to use this method because when clicking on commands from the view title
824827
* bar, the selections are not passed in.
825828
*
@@ -845,6 +848,13 @@ the file in the file explorer and dragging it into the workspace.`
845848
};
846849
}
847850
}
851+
852+
// ensure we do not return undefined
853+
if (singleItem && !multiSelect?.[0]) {
854+
multiSelect = [singleItem];
855+
} else if (!singleItem && multiSelect?.[0]) {
856+
singleItem = multiSelect[0];
857+
}
848858
return {
849859
finalSingleItem: singleItem,
850860
finalMultiSelect: multiSelect

extensions/ql-vscode/src/vscode-tests/no-workspace/query-history.test.ts

Lines changed: 161 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as vscode from 'vscode';
55
import * as sinon from 'sinon';
66
import * as chaiAsPromised from 'chai-as-promised';
77
import { logger } from '../../logging';
8-
import { QueryHistoryManager, HistoryTreeDataProvider } from '../../query-history';
8+
import { QueryHistoryManager, HistoryTreeDataProvider, SortOrder } from '../../query-history';
99
import { QueryEvaluationInfo, QueryWithResults } from '../../run-queries';
1010
import { QueryHistoryConfigListener } from '../../config';
1111
import * as messages from '../../pure/messages';
@@ -217,13 +217,14 @@ describe('query-history', () => {
217217
// will not change the selection
218218
const toDelete = allHistory[1];
219219
const selected = allHistory[3];
220-
// avoid triggering the callback by setting the field directly
221-
(queryHistoryManager.treeDataProvider as any).current = selected;
220+
221+
// select the item we want
222+
await queryHistoryManager.treeView.reveal(selected, { select: true });
222223
await queryHistoryManager.handleRemoveHistoryItem(toDelete, [toDelete]);
223224

224225
expect(toDelete.completedQuery!.dispose).to.have.been.calledOnce;
225-
expect(queryHistoryManager.treeDataProvider.getCurrent()).to.eq(selected);
226-
expect(allHistory).not.to.contain(toDelete);
226+
expect(queryHistoryManager.treeDataProvider.getCurrent()).to.deep.eq(selected);
227+
expect(queryHistoryManager.treeDataProvider.allHistory).not.to.contain(toDelete);
227228

228229
// the current item should have been re-selected
229230
expect(selectedCallback).to.have.been.calledOnceWith(selected);
@@ -236,12 +237,14 @@ describe('query-history', () => {
236237
const toDelete = allHistory[1];
237238
const newSelected = allHistory[2];
238239
// avoid triggering the callback by setting the field directly
239-
(queryHistoryManager.treeDataProvider as any).current = toDelete;
240+
241+
// select the item we want
242+
await queryHistoryManager.treeView.reveal(toDelete, { select: true });
240243
await queryHistoryManager.handleRemoveHistoryItem(toDelete, [toDelete]);
241244

242245
expect(toDelete.completedQuery!.dispose).to.have.been.calledOnce;
243246
expect(queryHistoryManager.treeDataProvider.getCurrent()).to.eq(newSelected);
244-
expect(allHistory).not.to.contain(toDelete);
247+
expect(queryHistoryManager.treeDataProvider.allHistory).not.to.contain(toDelete);
245248

246249
// the current item should have been selected
247250
expect(selectedCallback).to.have.been.calledOnceWith(newSelected);
@@ -356,6 +359,155 @@ describe('query-history', () => {
356359
});
357360
});
358361

362+
describe('determineSelection', () => {
363+
const singleItem = 'a';
364+
const multipleItems = ['b', 'c', 'd'];
365+
366+
it('should get the selection from parameters', async () => {
367+
queryHistoryManager = await createMockQueryHistory(allHistory);
368+
const selection = (queryHistoryManager as any).determineSelection(singleItem, multipleItems);
369+
expect(selection).to.deep.eq({
370+
finalSingleItem: singleItem,
371+
finalMultiSelect: multipleItems
372+
});
373+
});
374+
375+
it('should get the selection when single selection is empty', async () => {
376+
queryHistoryManager = await createMockQueryHistory(allHistory);
377+
const selection = (queryHistoryManager as any).determineSelection(undefined, multipleItems);
378+
expect(selection).to.deep.eq({
379+
finalSingleItem: multipleItems[0],
380+
finalMultiSelect: multipleItems
381+
});
382+
});
383+
384+
it('should get the selection when multi-selection is empty', async () => {
385+
queryHistoryManager = await createMockQueryHistory(allHistory);
386+
const selection = (queryHistoryManager as any).determineSelection(singleItem, undefined);
387+
expect(selection).to.deep.eq({
388+
finalSingleItem: singleItem,
389+
finalMultiSelect: [singleItem]
390+
});
391+
});
392+
393+
it('should get the selection from the treeView when both selections are empty', async () => {
394+
queryHistoryManager = await createMockQueryHistory(allHistory);
395+
await queryHistoryManager.treeView.reveal(allHistory[1], { select: true });
396+
const selection = (queryHistoryManager as any).determineSelection(undefined, undefined);
397+
expect(selection).to.deep.eq({
398+
finalSingleItem: allHistory[1],
399+
finalMultiSelect: [allHistory[1]]
400+
});
401+
});
402+
403+
it('should get the selection from the treeDataProvider when both selections and the treeView are empty', async () => {
404+
queryHistoryManager = await createMockQueryHistory(allHistory);
405+
await queryHistoryManager.treeView.reveal(allHistory[1], { select: true });
406+
const selection = (queryHistoryManager as any).determineSelection(undefined, undefined);
407+
expect(selection).to.deep.eq({
408+
finalSingleItem: allHistory[1],
409+
finalMultiSelect: [allHistory[1]]
410+
});
411+
});
412+
});
413+
414+
describe('getChildren', () => {
415+
const history = [
416+
item('a', 10, 20),
417+
item('b', 5, 30),
418+
item('c', 1, 25),
419+
];
420+
let treeDataProvider: HistoryTreeDataProvider;
421+
422+
beforeEach(async () => {
423+
queryHistoryManager = await createMockQueryHistory(allHistory);
424+
(queryHistoryManager.treeDataProvider as any).history = [...history];
425+
treeDataProvider = queryHistoryManager.treeDataProvider;
426+
});
427+
428+
it('should get children for name ascending', async () => {
429+
const expected = [...history];
430+
treeDataProvider.sortOrder = SortOrder.NameAsc;
431+
432+
const children = await treeDataProvider.getChildren();
433+
expect(children).to.deep.eq(expected);
434+
});
435+
436+
it('should get children for name descending', async () => {
437+
const expected = [...history].reverse();
438+
treeDataProvider.sortOrder = SortOrder.NameDesc;
439+
440+
const children = await treeDataProvider.getChildren();
441+
expect(children).to.deep.eq(expected);
442+
});
443+
444+
it('should get children for date ascending', async () => {
445+
const expected = [history[2], history[1], history[0]];
446+
treeDataProvider.sortOrder = SortOrder.DateAsc;
447+
448+
const children = await treeDataProvider.getChildren();
449+
expect(children).to.deep.eq(expected);
450+
});
451+
452+
it('should get children for date descending', async () => {
453+
const expected = [history[0], history[1], history[2]];
454+
treeDataProvider.sortOrder = SortOrder.DateDesc;
455+
456+
const children = await treeDataProvider.getChildren();
457+
expect(children).to.deep.eq(expected);
458+
});
459+
460+
it('should get children for result count ascending', async () => {
461+
const expected = [history[0], history[2], history[1]];
462+
treeDataProvider.sortOrder = SortOrder.CountAsc;
463+
464+
const children = await treeDataProvider.getChildren();
465+
expect(children).to.deep.eq(expected);
466+
});
467+
468+
it('should get children for result count descending', async () => {
469+
const expected = [history[1], history[2], history[0]];
470+
treeDataProvider.sortOrder = SortOrder.CountDesc;
471+
472+
const children = await treeDataProvider.getChildren();
473+
expect(children).to.deep.eq(expected);
474+
});
475+
476+
it('should get children for result count ascending when there are no results', async () => {
477+
// fall back to name
478+
const thisHistory = [item('a', 10), item('b', 50), item('c', 1)];
479+
(queryHistoryManager!.treeDataProvider as any).history = [...thisHistory];
480+
const expected = [...thisHistory];
481+
treeDataProvider.sortOrder = SortOrder.CountAsc;
482+
483+
const children = await treeDataProvider.getChildren();
484+
expect(children).to.deep.eq(expected);
485+
});
486+
487+
it('should get children for result count descending when there are no results', async () => {
488+
// fall back to name
489+
const thisHistory = [item('a', 10), item('b', 50), item('c', 1)];
490+
(queryHistoryManager!.treeDataProvider as any).history = [...thisHistory];
491+
const expected = [...thisHistory].reverse();
492+
treeDataProvider.sortOrder = SortOrder.CountDesc;
493+
494+
const children = await treeDataProvider.getChildren();
495+
expect(children).to.deep.eq(expected);
496+
});
497+
498+
function item(label: string, start: number, resultCount?: number) {
499+
return {
500+
label,
501+
initialInfo: {
502+
start: new Date(start),
503+
},
504+
completedQuery: {
505+
resultCount,
506+
}
507+
};
508+
}
509+
});
510+
359511
function createMockFullQueryInfo(dbName = 'a', queryWitbResults?: QueryWithResults, isFail = false): FullQueryInfo {
360512
const fqi = new FullQueryInfo(
361513
{
@@ -397,9 +549,9 @@ describe('query-history', () => {
397549
selectedCallback,
398550
doCompareCallback
399551
);
400-
(qhm.treeDataProvider as any).history = allHistory;
552+
(qhm.treeDataProvider as any).history = [...allHistory];
401553
await vscode.workspace.saveAll();
402-
554+
qhm.refreshTreeView();
403555
return qhm;
404556
}
405557
});

0 commit comments

Comments
 (0)