Merge branch 'main' into elena/disable-local-retry
This commit is contained in:
14
.github/codeql/queries/unique-command-use.ql
vendored
14
.github/codeql/queries/unique-command-use.ql
vendored
@@ -72,6 +72,20 @@
|
||||
|
||||
override string getCommandName() { result = this.getArgument(0).(StringLiteral).getValue() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A usage of a command from the typescript code, by calling `CommandManager.execute`.
|
||||
*/
|
||||
class CommandUsageCommandManagerMethodCallExpr extends CommandUsage, MethodCallExpr {
|
||||
CommandUsageCommandManagerMethodCallExpr() {
|
||||
this.getCalleeName() = "execute" and
|
||||
this.getReceiver().getType().unfold().(TypeReference).getTypeName().getName() = "CommandManager" and
|
||||
this.getArgument(0).(StringLiteral).getValue().matches("%codeQL%") and
|
||||
not this.getFile().getRelativePath().matches("extensions/ql-vscode/test/%")
|
||||
}
|
||||
|
||||
override string getCommandName() { result = this.getArgument(0).(StringLiteral).getValue() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A usage of a command from any menu that isn't the command palette.
|
||||
|
||||
46
extensions/ql-vscode/package-lock.json
generated
46
extensions/ql-vscode/package-lock.json
generated
@@ -54,7 +54,7 @@
|
||||
"@babel/core": "^7.18.13",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.18.6",
|
||||
"@faker-js/faker": "^7.5.0",
|
||||
"@octokit/plugin-throttling": "^4.3.2",
|
||||
"@octokit/plugin-throttling": "^5.0.1",
|
||||
"@storybook/addon-actions": "^6.5.10",
|
||||
"@storybook/addon-essentials": "^6.5.10",
|
||||
"@storybook/addon-interactions": "^6.5.10",
|
||||
@@ -5592,12 +5592,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-throttling": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-4.3.2.tgz",
|
||||
"integrity": "sha512-ZaCK599h3tzcoy0Jtdab95jgmD7X9iAk59E2E7hYKCAmnURaI4WpzwL9vckImilybUGrjY1JOWJapDs2N2D3vw==",
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-5.0.1.tgz",
|
||||
"integrity": "sha512-I4qxs7wYvYlFuY3PAUGWAVPhFXG3RwnvTiSr5Fu/Auz7bYhDLnzS2MjwV8nGLq/FPrWwYiweeZrI5yjs1YG4tQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@octokit/types": "^8.0.0",
|
||||
"@octokit/types": "^9.0.0",
|
||||
"bottleneck": "^2.15.3"
|
||||
},
|
||||
"engines": {
|
||||
@@ -5608,18 +5608,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-throttling/node_modules/@octokit/openapi-types": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-14.0.0.tgz",
|
||||
"integrity": "sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw==",
|
||||
"version": "16.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
|
||||
"integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@octokit/plugin-throttling/node_modules/@octokit/types": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.0.0.tgz",
|
||||
"integrity": "sha512-65/TPpOJP1i3K4lBJMnWqPUJ6zuOtzhtagDvydAWbEXpbFYA0oMKKyLb95NFZZP0lSh/4b6K+DQlzvYQJQQePg==",
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
|
||||
"integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^14.0.0"
|
||||
"@octokit/openapi-types": "^16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request": {
|
||||
@@ -45277,28 +45277,28 @@
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-throttling": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-4.3.2.tgz",
|
||||
"integrity": "sha512-ZaCK599h3tzcoy0Jtdab95jgmD7X9iAk59E2E7hYKCAmnURaI4WpzwL9vckImilybUGrjY1JOWJapDs2N2D3vw==",
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-5.0.1.tgz",
|
||||
"integrity": "sha512-I4qxs7wYvYlFuY3PAUGWAVPhFXG3RwnvTiSr5Fu/Auz7bYhDLnzS2MjwV8nGLq/FPrWwYiweeZrI5yjs1YG4tQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@octokit/types": "^8.0.0",
|
||||
"@octokit/types": "^9.0.0",
|
||||
"bottleneck": "^2.15.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-14.0.0.tgz",
|
||||
"integrity": "sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw==",
|
||||
"version": "16.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
|
||||
"integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA==",
|
||||
"dev": true
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.0.0.tgz",
|
||||
"integrity": "sha512-65/TPpOJP1i3K4lBJMnWqPUJ6zuOtzhtagDvydAWbEXpbFYA0oMKKyLb95NFZZP0lSh/4b6K+DQlzvYQJQQePg==",
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
|
||||
"integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^14.0.0"
|
||||
"@octokit/openapi-types": "^16.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1475,7 +1475,7 @@
|
||||
"@babel/core": "^7.18.13",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.18.6",
|
||||
"@faker-js/faker": "^7.5.0",
|
||||
"@octokit/plugin-throttling": "^4.3.2",
|
||||
"@octokit/plugin-throttling": "^5.0.1",
|
||||
"@storybook/addon-actions": "^6.5.10",
|
||||
"@storybook/addon-essentials": "^6.5.10",
|
||||
"@storybook/addon-interactions": "^6.5.10",
|
||||
|
||||
@@ -38,6 +38,7 @@ export type BuiltInVsCodeCommands = {
|
||||
// The codeQLDatabases.focus command is provided by VS Code because we've registered the custom view
|
||||
"codeQLDatabases.focus": () => Promise<void>;
|
||||
"markdown.showPreviewToSide": (uri: Uri) => Promise<void>;
|
||||
revealFileInOS: (uri: Uri) => Promise<void>;
|
||||
setContext: (
|
||||
key: `${"codeql" | "codeQL"}${string}`,
|
||||
value: unknown,
|
||||
|
||||
@@ -777,6 +777,7 @@ async function activateWithInstalledDistribution(
|
||||
};
|
||||
|
||||
const qhm = new QueryHistoryManager(
|
||||
app,
|
||||
qs,
|
||||
dbm,
|
||||
localQueryResultsView,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { join, dirname } from "path";
|
||||
import {
|
||||
commands,
|
||||
Disposable,
|
||||
env,
|
||||
EventEmitter,
|
||||
@@ -26,12 +25,7 @@ import { extLogger } from "../common";
|
||||
import { URLSearchParams } from "url";
|
||||
import { DisposableObject } from "../pure/disposable-object";
|
||||
import { ONE_HOUR_IN_MS, TWO_HOURS_IN_MS } from "../pure/time";
|
||||
import {
|
||||
asError,
|
||||
assertNever,
|
||||
getErrorMessage,
|
||||
getErrorStack,
|
||||
} from "../pure/helpers-pure";
|
||||
import { asError, assertNever, getErrorMessage } from "../pure/helpers-pure";
|
||||
import { CompletedLocalQueryInfo, LocalQueryInfo } from "../query-results";
|
||||
import {
|
||||
getActionsWorkflowRunUrl,
|
||||
@@ -66,6 +60,8 @@ import { HistoryTreeDataProvider } from "./history-tree-data-provider";
|
||||
import { redactableError } from "../pure/errors";
|
||||
import { QueryHistoryDirs } from "./query-history-dirs";
|
||||
import { QueryHistoryCommands } from "../common/commands";
|
||||
import { App } from "../common/app";
|
||||
import { tryOpenExternalFile } from "../vscode-utils/external-files";
|
||||
|
||||
/**
|
||||
* query-history-manager.ts
|
||||
@@ -135,6 +131,7 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
readonly onDidCompleteQuery = this._onDidCompleteQuery.event;
|
||||
|
||||
constructor(
|
||||
private readonly app: App,
|
||||
private readonly qs: QueryRunner,
|
||||
private readonly dbm: DatabaseManager,
|
||||
private readonly localQueriesResultsView: ResultsView,
|
||||
@@ -683,7 +680,10 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
}
|
||||
|
||||
if (singleItem.completedQuery.logFileLocation) {
|
||||
await this.tryOpenExternalFile(singleItem.completedQuery.logFileLocation);
|
||||
await tryOpenExternalFile(
|
||||
this.app.commands,
|
||||
singleItem.completedQuery.logFileLocation,
|
||||
);
|
||||
} else {
|
||||
void showAndLogWarningMessage("No log file available");
|
||||
}
|
||||
@@ -751,7 +751,7 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
}
|
||||
}
|
||||
try {
|
||||
await commands.executeCommand(
|
||||
await this.app.commands.execute(
|
||||
"revealFileInOS",
|
||||
Uri.file(externalFilePath),
|
||||
);
|
||||
@@ -800,7 +800,10 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
}
|
||||
|
||||
if (finalSingleItem.evalLogLocation) {
|
||||
await this.tryOpenExternalFile(finalSingleItem.evalLogLocation);
|
||||
await tryOpenExternalFile(
|
||||
this.app.commands,
|
||||
finalSingleItem.evalLogLocation,
|
||||
);
|
||||
} else {
|
||||
this.warnNoEvalLogs();
|
||||
}
|
||||
@@ -825,7 +828,10 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
}
|
||||
|
||||
if (finalSingleItem.evalLogSummaryLocation) {
|
||||
await this.tryOpenExternalFile(finalSingleItem.evalLogSummaryLocation);
|
||||
await tryOpenExternalFile(
|
||||
this.app.commands,
|
||||
finalSingleItem.evalLogSummaryLocation,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -968,7 +974,10 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
const query = finalSingleItem.completedQuery.query;
|
||||
const hasInterpretedResults = query.canHaveInterpretedResults();
|
||||
if (hasInterpretedResults) {
|
||||
await this.tryOpenExternalFile(query.resultsPaths.interpretedResultsPath);
|
||||
await tryOpenExternalFile(
|
||||
this.app.commands,
|
||||
query.resultsPaths.interpretedResultsPath,
|
||||
);
|
||||
} else {
|
||||
const label = this.labelProvider.getLabel(finalSingleItem);
|
||||
void showAndLogInformationMessage(
|
||||
@@ -997,11 +1006,11 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
}
|
||||
const query = finalSingleItem.completedQuery.query;
|
||||
if (await query.hasCsv()) {
|
||||
void this.tryOpenExternalFile(query.csvPath);
|
||||
void tryOpenExternalFile(this.app.commands, query.csvPath);
|
||||
return;
|
||||
}
|
||||
if (await query.exportCsvResults(this.qs.cliServer, query.csvPath)) {
|
||||
void this.tryOpenExternalFile(query.csvPath);
|
||||
void tryOpenExternalFile(this.app.commands, query.csvPath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1024,7 +1033,8 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.tryOpenExternalFile(
|
||||
await tryOpenExternalFile(
|
||||
this.app.commands,
|
||||
await finalSingleItem.completedQuery.query.ensureCsvAlerts(
|
||||
this.qs.cliServer,
|
||||
this.dbm,
|
||||
@@ -1051,7 +1061,8 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.tryOpenExternalFile(
|
||||
await tryOpenExternalFile(
|
||||
this.app.commands,
|
||||
await finalSingleItem.completedQuery.query.ensureDilPath(
|
||||
this.qs.cliServer,
|
||||
),
|
||||
@@ -1077,7 +1088,7 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
|
||||
const actionsWorkflowRunUrl = getActionsWorkflowRunUrl(finalSingleItem);
|
||||
|
||||
await commands.executeCommand(
|
||||
await this.app.commands.execute(
|
||||
"vscode.open",
|
||||
Uri.parse(actionsWorkflowRunUrl),
|
||||
);
|
||||
@@ -1101,7 +1112,7 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
return;
|
||||
}
|
||||
|
||||
await commands.executeCommand(
|
||||
await this.app.commands.execute(
|
||||
"codeQL.copyVariantAnalysisRepoList",
|
||||
finalSingleItem.variantAnalysis.id,
|
||||
);
|
||||
@@ -1171,47 +1182,6 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
}
|
||||
}
|
||||
|
||||
private async tryOpenExternalFile(fileLocation: string) {
|
||||
const uri = Uri.file(fileLocation);
|
||||
try {
|
||||
await window.showTextDocument(uri, { preview: false });
|
||||
} catch (e) {
|
||||
const msg = getErrorMessage(e);
|
||||
if (
|
||||
msg.includes(
|
||||
"Files above 50MB cannot be synchronized with extensions",
|
||||
) ||
|
||||
msg.includes("too large to open")
|
||||
) {
|
||||
const res = await showBinaryChoiceDialog(
|
||||
`VS Code does not allow extensions to open files >50MB. This file
|
||||
exceeds that limit. Do you want to open it outside of VS Code?
|
||||
|
||||
You can also try manually opening it inside VS Code by selecting
|
||||
the file in the file explorer and dragging it into the workspace.`,
|
||||
);
|
||||
if (res) {
|
||||
try {
|
||||
await commands.executeCommand("revealFileInOS", uri);
|
||||
} catch (e) {
|
||||
void showAndLogExceptionWithTelemetry(
|
||||
redactableError(
|
||||
asError(e),
|
||||
)`Failed to reveal file in OS: ${getErrorMessage(e)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
void showAndLogExceptionWithTelemetry(
|
||||
redactableError(asError(e))`Could not open file ${fileLocation}`,
|
||||
{
|
||||
fullMessage: `${getErrorMessage(e)}\n${getErrorStack(e)}`,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async findOtherQueryToCompare(
|
||||
singleItem: QueryHistoryInfo,
|
||||
multiSelect: QueryHistoryInfo[],
|
||||
|
||||
50
extensions/ql-vscode/src/vscode-utils/external-files.ts
Normal file
50
extensions/ql-vscode/src/vscode-utils/external-files.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { Uri, window } from "vscode";
|
||||
import { AppCommandManager } from "../common/commands";
|
||||
import {
|
||||
showAndLogExceptionWithTelemetry,
|
||||
showBinaryChoiceDialog,
|
||||
} from "../helpers";
|
||||
import { redactableError } from "../pure/errors";
|
||||
import { asError, getErrorMessage, getErrorStack } from "../pure/helpers-pure";
|
||||
|
||||
export async function tryOpenExternalFile(
|
||||
commandManager: AppCommandManager,
|
||||
fileLocation: string,
|
||||
) {
|
||||
const uri = Uri.file(fileLocation);
|
||||
try {
|
||||
await window.showTextDocument(uri, { preview: false });
|
||||
} catch (e) {
|
||||
const msg = getErrorMessage(e);
|
||||
if (
|
||||
msg.includes("Files above 50MB cannot be synchronized with extensions") ||
|
||||
msg.includes("too large to open")
|
||||
) {
|
||||
const res = await showBinaryChoiceDialog(
|
||||
`VS Code does not allow extensions to open files >50MB. This file
|
||||
exceeds that limit. Do you want to open it outside of VS Code?
|
||||
|
||||
You can also try manually opening it inside VS Code by selecting
|
||||
the file in the file explorer and dragging it into the workspace.`,
|
||||
);
|
||||
if (res) {
|
||||
try {
|
||||
await commandManager.execute("revealFileInOS", uri);
|
||||
} catch (e) {
|
||||
void showAndLogExceptionWithTelemetry(
|
||||
redactableError(
|
||||
asError(e),
|
||||
)`Failed to reveal file in OS: ${getErrorMessage(e)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
void showAndLogExceptionWithTelemetry(
|
||||
redactableError(asError(e))`Could not open file ${fileLocation}`,
|
||||
{
|
||||
fullMessage: `${getErrorMessage(e)}\n${getErrorStack(e)}`,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
} from "../../../../src/query-history/history-tree-data-provider";
|
||||
import { QueryHistoryManager } from "../../../../src/query-history/query-history-manager";
|
||||
import { createMockQueryHistoryDirs } from "../../../factories/query-history/query-history-dirs";
|
||||
import { createMockApp } from "../../../__mocks__/appMock";
|
||||
|
||||
describe("HistoryTreeDataProvider", () => {
|
||||
const mockExtensionLocation = join(tmpDir.name, "mock-extension-location");
|
||||
@@ -421,6 +422,7 @@ describe("HistoryTreeDataProvider", () => {
|
||||
|
||||
async function createMockQueryHistory(allHistory: QueryHistoryInfo[]) {
|
||||
const qhm = new QueryHistoryManager(
|
||||
createMockApp({}),
|
||||
{} as QueryRunner,
|
||||
{} as DatabaseManager,
|
||||
localQueriesResultsViewStub,
|
||||
|
||||
@@ -22,59 +22,49 @@ import { createMockVariantAnalysisHistoryItem } from "../../../factories/query-h
|
||||
import { VariantAnalysisHistoryItem } from "../../../../src/query-history/variant-analysis-history-item";
|
||||
import { QueryStatus } from "../../../../src/query-status";
|
||||
import { VariantAnalysisStatus } from "../../../../src/variant-analysis/shared/variant-analysis";
|
||||
import { TextEditor } from "vscode";
|
||||
import { WebviewReveal } from "../../../../src/interface-utils";
|
||||
import * as helpers from "../../../../src/helpers";
|
||||
import { mockedObject, mockedQuickPickItem } from "../../utils/mocking.helpers";
|
||||
import { mockedQuickPickItem } from "../../utils/mocking.helpers";
|
||||
import { createMockQueryHistoryDirs } from "../../../factories/query-history/query-history-dirs";
|
||||
import { createMockApp } from "../../../__mocks__/appMock";
|
||||
import { App } from "../../../../src/common/app";
|
||||
import { createMockCommandManager } from "../../../__mocks__/commandsMock";
|
||||
|
||||
describe("QueryHistoryManager", () => {
|
||||
const mockExtensionLocation = join(tmpDir.name, "mock-extension-location");
|
||||
let configListener: QueryHistoryConfigListener;
|
||||
let showTextDocumentSpy: jest.SpiedFunction<
|
||||
typeof vscode.window.showTextDocument
|
||||
>;
|
||||
let showInformationMessageSpy: jest.SpiedFunction<
|
||||
typeof vscode.window.showInformationMessage
|
||||
>;
|
||||
let showQuickPickSpy: jest.SpiedFunction<typeof vscode.window.showQuickPick>;
|
||||
let executeCommandSpy: jest.SpiedFunction<
|
||||
typeof vscode.commands.executeCommand
|
||||
>;
|
||||
let cancelVariantAnalysisSpy: jest.SpiedFunction<
|
||||
typeof variantAnalysisManagerStub.cancelVariantAnalysis
|
||||
>;
|
||||
const doCompareCallback = jest.fn();
|
||||
|
||||
let executeCommand: jest.MockedFn<
|
||||
(commandName: string, ...args: any[]) => Promise<any>
|
||||
>;
|
||||
let mockApp: App;
|
||||
|
||||
let queryHistoryManager: QueryHistoryManager;
|
||||
|
||||
let localQueriesResultsViewStub: ResultsView;
|
||||
let variantAnalysisManagerStub: VariantAnalysisManager;
|
||||
|
||||
let tryOpenExternalFile: Function;
|
||||
|
||||
let allHistory: QueryHistoryInfo[];
|
||||
let localQueryHistory: LocalQueryInfo[];
|
||||
let variantAnalysisHistory: VariantAnalysisHistoryItem[];
|
||||
|
||||
beforeEach(() => {
|
||||
showTextDocumentSpy = jest
|
||||
.spyOn(vscode.window, "showTextDocument")
|
||||
.mockResolvedValue(mockedObject<TextEditor>({}));
|
||||
showInformationMessageSpy = jest
|
||||
.spyOn(vscode.window, "showInformationMessage")
|
||||
.mockResolvedValue(undefined);
|
||||
showQuickPickSpy = jest
|
||||
.spyOn(vscode.window, "showQuickPick")
|
||||
.mockResolvedValue(undefined);
|
||||
executeCommandSpy = jest
|
||||
.spyOn(vscode.commands, "executeCommand")
|
||||
.mockResolvedValue(undefined);
|
||||
|
||||
executeCommand = jest.fn();
|
||||
mockApp = createMockApp({
|
||||
commands: createMockCommandManager({ executeCommand }),
|
||||
});
|
||||
|
||||
jest.spyOn(extLogger, "log").mockResolvedValue(undefined);
|
||||
|
||||
tryOpenExternalFile = (QueryHistoryManager.prototype as any)
|
||||
.tryOpenExternalFile;
|
||||
configListener = new QueryHistoryConfigListener();
|
||||
localQueriesResultsViewStub = {
|
||||
showResults: jest.fn(),
|
||||
@@ -157,51 +147,6 @@ describe("QueryHistoryManager", () => {
|
||||
queryHistoryManager.dispose();
|
||||
}
|
||||
});
|
||||
describe("tryOpenExternalFile", () => {
|
||||
it("should open an external file", async () => {
|
||||
await tryOpenExternalFile("xxx");
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledWith(
|
||||
vscode.Uri.file("xxx"),
|
||||
expect.anything(),
|
||||
);
|
||||
expect(executeCommandSpy).not.toBeCalled();
|
||||
});
|
||||
|
||||
[
|
||||
"too large to open",
|
||||
"Files above 50MB cannot be synchronized with extensions",
|
||||
].forEach((msg) => {
|
||||
it(`should fail to open a file because "${msg}" and open externally`, async () => {
|
||||
showTextDocumentSpy.mockRejectedValue(new Error(msg));
|
||||
showInformationMessageSpy.mockResolvedValue({ title: "Yes" });
|
||||
|
||||
await tryOpenExternalFile("xxx");
|
||||
const uri = vscode.Uri.file("xxx");
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledWith(
|
||||
uri,
|
||||
expect.anything(),
|
||||
);
|
||||
expect(executeCommandSpy).toHaveBeenCalledWith("revealFileInOS", uri);
|
||||
});
|
||||
|
||||
it(`should fail to open a file because "${msg}" and NOT open externally`, async () => {
|
||||
showTextDocumentSpy.mockRejectedValue(new Error(msg));
|
||||
showInformationMessageSpy.mockResolvedValue({ title: "No" });
|
||||
|
||||
await tryOpenExternalFile("xxx");
|
||||
const uri = vscode.Uri.file("xxx");
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledWith(
|
||||
uri,
|
||||
expect.anything(),
|
||||
);
|
||||
expect(showInformationMessageSpy).toBeCalled();
|
||||
expect(executeCommandSpy).not.toBeCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("handleItemClicked", () => {
|
||||
describe("single click", () => {
|
||||
@@ -832,7 +777,7 @@ describe("QueryHistoryManager", () => {
|
||||
const item = localQueryHistory[4];
|
||||
await queryHistoryManager.handleCopyRepoList(item, [item]);
|
||||
|
||||
expect(executeCommandSpy).not.toBeCalled();
|
||||
expect(executeCommand).not.toBeCalled();
|
||||
});
|
||||
|
||||
it("should copy repo list for a single variant analysis", async () => {
|
||||
@@ -840,7 +785,7 @@ describe("QueryHistoryManager", () => {
|
||||
|
||||
const item = variantAnalysisHistory[1];
|
||||
await queryHistoryManager.handleCopyRepoList(item, [item]);
|
||||
expect(executeCommandSpy).toBeCalledWith(
|
||||
expect(executeCommand).toBeCalledWith(
|
||||
"codeQL.copyVariantAnalysisRepoList",
|
||||
item.variantAnalysis.id,
|
||||
);
|
||||
@@ -852,7 +797,7 @@ describe("QueryHistoryManager", () => {
|
||||
const item1 = variantAnalysisHistory[1];
|
||||
const item2 = variantAnalysisHistory[3];
|
||||
await queryHistoryManager.handleCopyRepoList(item1, [item1, item2]);
|
||||
expect(executeCommandSpy).not.toBeCalled();
|
||||
expect(executeCommand).not.toBeCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1149,6 +1094,7 @@ describe("QueryHistoryManager", () => {
|
||||
|
||||
async function createMockQueryHistory(allHistory: QueryHistoryInfo[]) {
|
||||
const qhm = new QueryHistoryManager(
|
||||
mockApp,
|
||||
{} as QueryRunner,
|
||||
{} as DatabaseManager,
|
||||
localQueriesResultsViewStub,
|
||||
|
||||
@@ -21,6 +21,7 @@ import { VariantAnalysisManager } from "../../../../src/variant-analysis/variant
|
||||
import { QueryHistoryManager } from "../../../../src/query-history/query-history-manager";
|
||||
import { mockedObject } from "../../utils/mocking.helpers";
|
||||
import { createMockQueryHistoryDirs } from "../../../factories/query-history/query-history-dirs";
|
||||
import { createMockApp } from "../../../__mocks__/appMock";
|
||||
|
||||
// set a higher timeout since recursive delete may take a while, expecially on Windows.
|
||||
jest.setTimeout(120000);
|
||||
@@ -73,6 +74,7 @@ describe("Variant Analyses and QueryHistoryManager", () => {
|
||||
).queries;
|
||||
|
||||
qhm = new QueryHistoryManager(
|
||||
createMockApp({}),
|
||||
{} as QueryRunner,
|
||||
{} as DatabaseManager,
|
||||
localQueriesResultsViewStub,
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
import * as vscode from "vscode";
|
||||
import { tryOpenExternalFile } from "../../../../../src/vscode-utils/external-files";
|
||||
import { createMockCommandManager } from "../../../../__mocks__/commandsMock";
|
||||
import { mockedObject } from "../../../utils/mocking.helpers";
|
||||
|
||||
describe("tryOpenExternalFile", () => {
|
||||
let showTextDocumentSpy: jest.SpiedFunction<
|
||||
typeof vscode.window.showTextDocument
|
||||
>;
|
||||
let showInformationMessageSpy: jest.SpiedFunction<
|
||||
typeof vscode.window.showInformationMessage
|
||||
>;
|
||||
|
||||
beforeEach(() => {
|
||||
showTextDocumentSpy = jest
|
||||
.spyOn(vscode.window, "showTextDocument")
|
||||
.mockResolvedValue(mockedObject<vscode.TextEditor>({}));
|
||||
showInformationMessageSpy = jest
|
||||
.spyOn(vscode.window, "showInformationMessage")
|
||||
.mockResolvedValue(undefined);
|
||||
});
|
||||
|
||||
it("should open an external file", async () => {
|
||||
const executeCommand = jest.fn();
|
||||
const commandManager = createMockCommandManager({ executeCommand });
|
||||
|
||||
await tryOpenExternalFile(commandManager, "xxx");
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledWith(
|
||||
vscode.Uri.file("xxx"),
|
||||
expect.anything(),
|
||||
);
|
||||
expect(executeCommand).not.toBeCalled();
|
||||
});
|
||||
|
||||
[
|
||||
"too large to open",
|
||||
"Files above 50MB cannot be synchronized with extensions",
|
||||
].forEach((msg) => {
|
||||
it(`should fail to open a file because "${msg}" and open externally`, async () => {
|
||||
const executeCommand = jest.fn();
|
||||
const commandManager = createMockCommandManager({ executeCommand });
|
||||
|
||||
showTextDocumentSpy.mockRejectedValue(new Error(msg));
|
||||
showInformationMessageSpy.mockResolvedValue({ title: "Yes" });
|
||||
|
||||
await tryOpenExternalFile(commandManager, "xxx");
|
||||
const uri = vscode.Uri.file("xxx");
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledWith(uri, expect.anything());
|
||||
expect(executeCommand).toHaveBeenCalledWith("revealFileInOS", uri);
|
||||
});
|
||||
|
||||
it(`should fail to open a file because "${msg}" and NOT open externally`, async () => {
|
||||
const executeCommand = jest.fn();
|
||||
const commandManager = createMockCommandManager({ executeCommand });
|
||||
|
||||
showTextDocumentSpy.mockRejectedValue(new Error(msg));
|
||||
showInformationMessageSpy.mockResolvedValue({ title: "No" });
|
||||
|
||||
await tryOpenExternalFile(commandManager, "xxx");
|
||||
const uri = vscode.Uri.file("xxx");
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showTextDocumentSpy).toHaveBeenCalledWith(uri, expect.anything());
|
||||
expect(showInformationMessageSpy).toBeCalled();
|
||||
expect(executeCommand).not.toBeCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user