Queries Panel: Create query from welcome view (#2780)
This commit is contained in:
@@ -1804,7 +1804,8 @@
|
||||
},
|
||||
{
|
||||
"view": "codeQLQueries",
|
||||
"contents": "Looking for queries..."
|
||||
"contents": "We didn't find any CodeQL queries in this workspace. [Create one to get started](command:codeQLQueries.createQuery).",
|
||||
"when": "codeQL.noQueries"
|
||||
},
|
||||
{
|
||||
"view": "codeQLDatabases",
|
||||
|
||||
@@ -44,7 +44,7 @@ export class QueriesModule extends DisposableObject {
|
||||
this.push(queryDiscovery);
|
||||
void queryDiscovery.initialRefresh();
|
||||
|
||||
this.queriesPanel = new QueriesPanel(queryDiscovery);
|
||||
this.queriesPanel = new QueriesPanel(queryDiscovery, app);
|
||||
this.push(this.queriesPanel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,16 @@ import { DisposableObject } from "../common/disposable-object";
|
||||
import { QueryTreeDataProvider } from "./query-tree-data-provider";
|
||||
import { QueryDiscovery } from "./query-discovery";
|
||||
import { window } from "vscode";
|
||||
import { App } from "../common/app";
|
||||
|
||||
export class QueriesPanel extends DisposableObject {
|
||||
public constructor(queryDiscovery: QueryDiscovery) {
|
||||
public constructor(
|
||||
queryDiscovery: QueryDiscovery,
|
||||
readonly app: App,
|
||||
) {
|
||||
super();
|
||||
|
||||
const dataProvider = new QueryTreeDataProvider(queryDiscovery);
|
||||
const dataProvider = new QueryTreeDataProvider(queryDiscovery, app);
|
||||
|
||||
const treeView = window.createTreeView("codeQLQueries", {
|
||||
treeDataProvider: dataProvider,
|
||||
|
||||
@@ -3,10 +3,10 @@ import {
|
||||
QueryTreeViewItem,
|
||||
createQueryTreeFileItem,
|
||||
createQueryTreeFolderItem,
|
||||
createQueryTreeTextItem,
|
||||
} from "./query-tree-view-item";
|
||||
import { DisposableObject } from "../common/disposable-object";
|
||||
import { FileTreeNode } from "../common/file-tree-nodes";
|
||||
import { App } from "../common/app";
|
||||
|
||||
export interface QueryDiscoverer {
|
||||
readonly buildQueryTree: () => Array<FileTreeNode<string>> | undefined;
|
||||
@@ -23,7 +23,10 @@ export class QueryTreeDataProvider
|
||||
new EventEmitter<void>(),
|
||||
);
|
||||
|
||||
public constructor(private readonly queryDiscoverer: QueryDiscoverer) {
|
||||
public constructor(
|
||||
private readonly queryDiscoverer: QueryDiscoverer,
|
||||
private readonly app: App,
|
||||
) {
|
||||
super();
|
||||
|
||||
queryDiscoverer.onDidChangeQueries(() => {
|
||||
@@ -43,8 +46,11 @@ export class QueryTreeDataProvider
|
||||
if (queryTree === undefined) {
|
||||
return [];
|
||||
} else if (queryTree.length === 0) {
|
||||
return [this.noQueriesTreeViewItem()];
|
||||
void this.app.commands.execute("setContext", "codeQL.noQueries", true);
|
||||
// Returning an empty tree here will show the welcome view
|
||||
return [];
|
||||
} else {
|
||||
void this.app.commands.execute("setContext", "codeQL.noQueries", false);
|
||||
return queryTree.map(this.convertFileTreeNode.bind(this));
|
||||
}
|
||||
}
|
||||
@@ -67,12 +73,6 @@ export class QueryTreeDataProvider
|
||||
}
|
||||
}
|
||||
|
||||
private noQueriesTreeViewItem(): QueryTreeViewItem {
|
||||
return createQueryTreeTextItem(
|
||||
"This workspace doesn't contain any CodeQL queries at the moment.",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the UI presentation of the element that gets displayed in the view.
|
||||
* @param item The item to represent.
|
||||
|
||||
@@ -39,7 +39,3 @@ export function createQueryTreeFileItem(
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
export function createQueryTreeTextItem(text: string): QueryTreeViewItem {
|
||||
return new QueryTreeViewItem(text, undefined, []);
|
||||
}
|
||||
|
||||
@@ -7,56 +7,71 @@ import { QueryTreeDataProvider } from "../../../../src/queries-panel/query-tree-
|
||||
import {
|
||||
createQueryTreeFileItem,
|
||||
createQueryTreeFolderItem,
|
||||
createQueryTreeTextItem,
|
||||
} from "../../../../src/queries-panel/query-tree-view-item";
|
||||
import { createMockApp } from "../../../__mocks__/appMock";
|
||||
import { createMockCommandManager } from "../../../__mocks__/commandsMock";
|
||||
|
||||
describe("QueryTreeDataProvider", () => {
|
||||
describe("getChildren", () => {
|
||||
it("returns empty array when discovery has not yet happened", async () => {
|
||||
const dataProvider = new QueryTreeDataProvider({
|
||||
buildQueryTree: () => undefined,
|
||||
onDidChangeQueries: jest.fn(),
|
||||
});
|
||||
const dataProvider = new QueryTreeDataProvider(
|
||||
{
|
||||
buildQueryTree: () => undefined,
|
||||
onDidChangeQueries: jest.fn(),
|
||||
},
|
||||
createMockApp({}),
|
||||
);
|
||||
|
||||
expect(dataProvider.getChildren()).toEqual([]);
|
||||
});
|
||||
|
||||
it("returns an explanatory message when there are no queries", async () => {
|
||||
const dataProvider = new QueryTreeDataProvider({
|
||||
buildQueryTree: () => [],
|
||||
onDidChangeQueries: jest.fn(),
|
||||
});
|
||||
it("set 'noQueries' context value when there are no queries", async () => {
|
||||
const executeCommand = jest.fn();
|
||||
|
||||
expect(dataProvider.getChildren()).toEqual([
|
||||
createQueryTreeTextItem(
|
||||
"This workspace doesn't contain any CodeQL queries at the moment.",
|
||||
),
|
||||
]);
|
||||
const dataProvider = new QueryTreeDataProvider(
|
||||
{
|
||||
buildQueryTree: () => [],
|
||||
onDidChangeQueries: jest.fn(),
|
||||
},
|
||||
createMockApp({
|
||||
commands: createMockCommandManager({ executeCommand }),
|
||||
}),
|
||||
);
|
||||
|
||||
expect(dataProvider.getChildren()).toEqual([]);
|
||||
expect(executeCommand).toBeCalledWith(
|
||||
"setContext",
|
||||
"codeQL.noQueries",
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it("converts FileTreeNode to QueryTreeViewItem", async () => {
|
||||
const dataProvider = new QueryTreeDataProvider({
|
||||
buildQueryTree: () => [
|
||||
new FileTreeDirectory<string>("dir1", "dir1", env, [
|
||||
new FileTreeDirectory<string>("dir1/dir2", "dir2", env, [
|
||||
new FileTreeLeaf<string>(
|
||||
"dir1/dir2/file1",
|
||||
"file1",
|
||||
"javascript",
|
||||
),
|
||||
new FileTreeLeaf<string>(
|
||||
"dir1/dir2/file2",
|
||||
"file2",
|
||||
"javascript",
|
||||
),
|
||||
const dataProvider = new QueryTreeDataProvider(
|
||||
{
|
||||
buildQueryTree: () => [
|
||||
new FileTreeDirectory<string>("dir1", "dir1", env, [
|
||||
new FileTreeDirectory<string>("dir1/dir2", "dir2", env, [
|
||||
new FileTreeLeaf<string>(
|
||||
"dir1/dir2/file1",
|
||||
"file1",
|
||||
"javascript",
|
||||
),
|
||||
new FileTreeLeaf<string>(
|
||||
"dir1/dir2/file2",
|
||||
"file2",
|
||||
"javascript",
|
||||
),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
new FileTreeDirectory<string>("dir3", "dir3", env, [
|
||||
new FileTreeLeaf<string>("dir3/file3", "file3", "javascript"),
|
||||
]),
|
||||
],
|
||||
onDidChangeQueries: jest.fn(),
|
||||
});
|
||||
new FileTreeDirectory<string>("dir3", "dir3", env, [
|
||||
new FileTreeLeaf<string>("dir3/file3", "file3", "javascript"),
|
||||
]),
|
||||
],
|
||||
onDidChangeQueries: jest.fn(),
|
||||
},
|
||||
createMockApp({}),
|
||||
);
|
||||
|
||||
expect(dataProvider.getChildren()).toEqual([
|
||||
createQueryTreeFolderItem("dir1", "dir1", [
|
||||
@@ -85,7 +100,14 @@ describe("QueryTreeDataProvider", () => {
|
||||
onDidChangeQueries: onDidChangeQueriesEmitter.event,
|
||||
};
|
||||
|
||||
const dataProvider = new QueryTreeDataProvider(queryDiscoverer);
|
||||
const executeCommand = jest.fn();
|
||||
|
||||
const dataProvider = new QueryTreeDataProvider(
|
||||
queryDiscoverer,
|
||||
createMockApp({
|
||||
commands: createMockCommandManager({ executeCommand }),
|
||||
}),
|
||||
);
|
||||
expect(dataProvider.getChildren().length).toEqual(1);
|
||||
|
||||
queryTree.push(
|
||||
@@ -96,6 +118,11 @@ describe("QueryTreeDataProvider", () => {
|
||||
onDidChangeQueriesEmitter.fire();
|
||||
|
||||
expect(dataProvider.getChildren().length).toEqual(2);
|
||||
expect(executeCommand).toBeCalledWith(
|
||||
"setContext",
|
||||
"codeQL.noQueries",
|
||||
false,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user