Skip to content

Commit 86b53a8

Browse files
Merge pull request github#2358 from github/robertbrignull/handleCompareWith
Fiddle with handleCompareWith to make it cleaner
2 parents 298176d + 912a9e1 commit 86b53a8

File tree

4 files changed

+85
-82
lines changed

4 files changed

+85
-82
lines changed

extensions/ql-vscode/src/query-history/history-item-label-provider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export class HistoryItemLabelProvider {
8080
return {
8181
t: item.startTime,
8282
q: item.getQueryName(),
83-
d: item.initialInfo.databaseInfo.name,
83+
d: item.databaseName,
8484
r: `(${resultCount} results)`,
8585
s: statusString,
8686
f: item.getQueryFileName(),

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

Lines changed: 60 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import {
1515
import { QueryHistoryConfig } from "../config";
1616
import {
1717
showAndLogErrorMessage,
18-
showAndLogExceptionWithTelemetry,
1918
showAndLogInformationMessage,
2019
showAndLogWarningMessage,
2120
showBinaryChoiceDialog,
@@ -25,7 +24,7 @@ import { extLogger } from "../common";
2524
import { URLSearchParams } from "url";
2625
import { DisposableObject } from "../pure/disposable-object";
2726
import { ONE_HOUR_IN_MS, TWO_HOURS_IN_MS } from "../pure/time";
28-
import { asError, assertNever, getErrorMessage } from "../pure/helpers-pure";
27+
import { assertNever, getErrorMessage } from "../pure/helpers-pure";
2928
import { CompletedLocalQueryInfo, LocalQueryInfo } from "../query-results";
3029
import {
3130
getActionsWorkflowRunUrl,
@@ -54,7 +53,6 @@ import { VariantAnalysisManager } from "../variant-analysis/variant-analysis-man
5453
import { VariantAnalysisHistoryItem } from "./variant-analysis-history-item";
5554
import { getTotalResultCount } from "../variant-analysis/shared/variant-analysis";
5655
import { HistoryTreeDataProvider } from "./history-tree-data-provider";
57-
import { redactableError } from "../pure/errors";
5856
import { QueryHistoryDirs } from "./query-history-dirs";
5957
import { QueryHistoryCommands } from "../common/commands";
6058
import { App } from "../common/app";
@@ -573,40 +571,41 @@ export class QueryHistoryManager extends DisposableObject {
573571
}
574572
}
575573

574+
isSuccessfulCompletedLocalQueryInfo(
575+
item: QueryHistoryInfo,
576+
): item is CompletedLocalQueryInfo {
577+
return item.t === "local" && item.completedQuery?.successful === true;
578+
}
579+
576580
async handleCompareWith(
577581
singleItem: QueryHistoryInfo,
578582
multiSelect: QueryHistoryInfo[] | undefined,
579583
) {
580584
multiSelect ||= [singleItem];
581585

582-
try {
583-
// local queries only
584-
if (singleItem?.t !== "local") {
585-
throw new Error("Please select a local query.");
586-
}
587-
588-
if (!singleItem.completedQuery?.successful) {
589-
throw new Error(
590-
"Please select a query that has completed successfully.",
591-
);
592-
}
586+
if (
587+
!this.isSuccessfulCompletedLocalQueryInfo(singleItem) ||
588+
!multiSelect.every(this.isSuccessfulCompletedLocalQueryInfo)
589+
) {
590+
throw new Error(
591+
"Please only select local queries that have completed successfully.",
592+
);
593+
}
593594

594-
const from = this.compareWithItem || singleItem;
595-
const to = await this.findOtherQueryToCompare(from, multiSelect);
595+
const fromItem = this.getFromQueryToCompare(singleItem, multiSelect);
596596

597-
if (from.completed && to?.completed) {
598-
await this.doCompareCallback(
599-
from as CompletedLocalQueryInfo,
600-
to as CompletedLocalQueryInfo,
601-
);
602-
}
597+
let toItem: CompletedLocalQueryInfo | undefined = undefined;
598+
try {
599+
toItem = await this.findOtherQueryToCompare(fromItem, multiSelect);
603600
} catch (e) {
604-
void showAndLogExceptionWithTelemetry(
605-
redactableError(
606-
asError(e),
607-
)`Failed to compare queries: ${getErrorMessage(e)}`,
601+
void showAndLogErrorMessage(
602+
`Failed to compare queries: ${getErrorMessage(e)}`,
608603
);
609604
}
605+
606+
if (toItem !== undefined) {
607+
await this.doCompareCallback(fromItem, toItem);
608+
}
610609
}
611610

612611
async handleItemClicked(
@@ -1066,58 +1065,56 @@ export class QueryHistoryManager extends DisposableObject {
10661065
}
10671066
}
10681067

1069-
private async findOtherQueryToCompare(
1070-
singleItem: QueryHistoryInfo,
1071-
multiSelect: QueryHistoryInfo[],
1072-
): Promise<CompletedLocalQueryInfo | undefined> {
1073-
// Variant analyses cannot be compared
1068+
private getFromQueryToCompare(
1069+
singleItem: CompletedLocalQueryInfo,
1070+
multiSelect: CompletedLocalQueryInfo[],
1071+
): CompletedLocalQueryInfo {
10741072
if (
1075-
singleItem.t !== "local" ||
1076-
multiSelect.some((s) => s.t !== "local") ||
1077-
!singleItem.completedQuery
1073+
this.compareWithItem &&
1074+
this.isSuccessfulCompletedLocalQueryInfo(this.compareWithItem) &&
1075+
multiSelect.includes(this.compareWithItem)
10781076
) {
1079-
return undefined;
1077+
return this.compareWithItem;
1078+
} else {
1079+
return singleItem;
10801080
}
1081-
const dbName = singleItem.initialInfo.databaseInfo.name;
1082-
1083-
// if exactly 2 queries are selected, use those
1084-
if (multiSelect?.length === 2) {
1085-
// return the query that is not the first selected one
1086-
const otherQuery = (
1087-
singleItem === multiSelect[0] ? multiSelect[1] : multiSelect[0]
1088-
) as LocalQueryInfo;
1089-
if (!otherQuery.completedQuery) {
1090-
throw new Error("Please select a completed query.");
1091-
}
1092-
if (!otherQuery.completedQuery.successful) {
1093-
throw new Error("Please select a successful query.");
1094-
}
1095-
if (otherQuery.initialInfo.databaseInfo.name !== dbName) {
1081+
}
1082+
1083+
private async findOtherQueryToCompare(
1084+
fromItem: CompletedLocalQueryInfo,
1085+
allSelectedItems: CompletedLocalQueryInfo[],
1086+
): Promise<CompletedLocalQueryInfo | undefined> {
1087+
const dbName = fromItem.databaseName;
1088+
1089+
// If exactly 2 items are selected, return the one that
1090+
// isn't being used as the "from" item.
1091+
if (allSelectedItems.length === 2) {
1092+
const otherItem =
1093+
fromItem === allSelectedItems[0]
1094+
? allSelectedItems[1]
1095+
: allSelectedItems[0];
1096+
if (otherItem.databaseName !== dbName) {
10961097
throw new Error("Query databases must be the same.");
10971098
}
1098-
return otherQuery as CompletedLocalQueryInfo;
1099+
return otherItem;
10991100
}
11001101

1101-
if (multiSelect?.length > 2) {
1102+
if (allSelectedItems.length > 2) {
11021103
throw new Error("Please select no more than 2 queries.");
11031104
}
11041105

1105-
// otherwise, let the user choose
1106+
// Otherwise, present a dialog so the user can choose the item they want to use.
11061107
const comparableQueryLabels = this.treeDataProvider.allHistory
1108+
.filter(this.isSuccessfulCompletedLocalQueryInfo)
11071109
.filter(
1108-
(otherQuery) =>
1109-
otherQuery !== singleItem &&
1110-
otherQuery.t === "local" &&
1111-
otherQuery.completedQuery &&
1112-
otherQuery.completedQuery.successful &&
1113-
otherQuery.initialInfo.databaseInfo.name === dbName,
1110+
(otherItem) =>
1111+
otherItem !== fromItem && otherItem.databaseName === dbName,
11141112
)
11151113
.map((item) => ({
11161114
label: this.labelProvider.getLabel(item),
1117-
description: (item as CompletedLocalQueryInfo).initialInfo.databaseInfo
1118-
.name,
1119-
detail: (item as CompletedLocalQueryInfo).completedQuery.statusString,
1120-
query: item as CompletedLocalQueryInfo,
1115+
description: item.databaseName,
1116+
detail: item.completedQuery.statusString,
1117+
query: item,
11211118
}));
11221119
if (comparableQueryLabels.length < 1) {
11231120
throw new Error("No other queries available to compare with.");

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,4 +313,8 @@ export class LocalQueryInfo {
313313
return QueryStatus.Failed;
314314
}
315315
}
316+
317+
get databaseName() {
318+
return this.initialInfo.databaseInfo.name;
319+
}
316320
}

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

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -876,24 +876,6 @@ describe("QueryHistoryManager", () => {
876876
expect(showQuickPickSpy).not.toBeCalled();
877877
});
878878

879-
it("should throw an error when a query is not successful", async () => {
880-
const thisQuery = localQueryHistory[3];
881-
queryHistoryManager = await createMockQueryHistory(allHistory);
882-
allHistory[0] = createMockLocalQueryInfo({
883-
dbName: "a",
884-
queryWithResults: createMockQueryWithResults({
885-
didRunSuccessfully: false,
886-
}),
887-
});
888-
889-
await expect(
890-
(queryHistoryManager as any).findOtherQueryToCompare(thisQuery, [
891-
thisQuery,
892-
allHistory[0],
893-
]),
894-
).rejects.toThrow("Please select a successful query.");
895-
});
896-
897879
it("should throw an error when a databases are not the same", async () => {
898880
queryHistoryManager = await createMockQueryHistory(allHistory);
899881

@@ -942,6 +924,26 @@ describe("QueryHistoryManager", () => {
942924
]);
943925
expect(doCompareCallback).not.toBeCalled();
944926
});
927+
928+
it("should throw an error when a query is not successful", async () => {
929+
const thisQuery = localQueryHistory[3];
930+
queryHistoryManager = await createMockQueryHistory(allHistory);
931+
allHistory[0] = createMockLocalQueryInfo({
932+
dbName: "a",
933+
queryWithResults: createMockQueryWithResults({
934+
didRunSuccessfully: false,
935+
}),
936+
});
937+
938+
await expect(
939+
queryHistoryManager.handleCompareWith(thisQuery, [
940+
thisQuery,
941+
allHistory[0],
942+
]),
943+
).rejects.toThrow(
944+
"Please only select local queries that have completed successfully.",
945+
);
946+
});
945947
});
946948

947949
describe("updateCompareWith", () => {

0 commit comments

Comments
 (0)