From ee056ce2b3c0074b1446cc984f450b565f373318 Mon Sep 17 00:00:00 2001 From: Nora Date: Fri, 2 Dec 2022 15:22:14 +0100 Subject: [PATCH 1/7] Create method to expose selected DbItem --- extensions/ql-vscode/src/databases/db-item.ts | 32 +++++++++++++++++++ .../ql-vscode/src/databases/db-manager.ts | 12 ++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/extensions/ql-vscode/src/databases/db-item.ts b/extensions/ql-vscode/src/databases/db-item.ts index 76bda03c6bc..d56f6cb7067 100644 --- a/extensions/ql-vscode/src/databases/db-item.ts +++ b/extensions/ql-vscode/src/databases/db-item.ts @@ -124,3 +124,35 @@ const SelectableDbItemKinds = [ DbItemKind.RemoteOwner, DbItemKind.RemoteRepo, ]; + +export function getSelectedDbItem(dbItems: DbItem[]): DbItem | undefined { + for (const dbItem of dbItems) { + if ( + dbItem.kind === DbItemKind.RootRemote || + dbItem.kind === DbItemKind.RootLocal + ) { + for (const child of dbItem.children) { + switch (child.kind) { + case DbItemKind.LocalList: + for (const database of child.databases) { + if (database.selected) { + return database; + } + } + break; + case DbItemKind.RemoteUserDefinedList: + for (const repo of child.repos) { + if (repo.selected) { + return repo; + } + } + break; + default: + if (child.selected) { + return child; + } + } + } + } + } +} diff --git a/extensions/ql-vscode/src/databases/db-manager.ts b/extensions/ql-vscode/src/databases/db-manager.ts index 32317c99c51..a3395f3b795 100644 --- a/extensions/ql-vscode/src/databases/db-manager.ts +++ b/extensions/ql-vscode/src/databases/db-manager.ts @@ -2,7 +2,7 @@ import { App } from "../common/app"; import { AppEvent, AppEventEmitter } from "../common/events"; import { ValueResult } from "../common/value-result"; import { DbConfigStore } from "./config/db-config-store"; -import { DbItem } from "./db-item"; +import { DbItem, getSelectedDbItem } from "./db-item"; import { createLocalTree, createRemoteTree } from "./db-tree-creator"; export class DbManager { @@ -18,6 +18,16 @@ export class DbManager { }); } + public selectedDbItem(): DbItem | undefined { + const dbItems = this.getDbItems(); + + if (dbItems.isFailure) { + return undefined; + } + + return getSelectedDbItem(dbItems.value); + } + public getDbItems(): ValueResult { const configResult = this.dbConfigStore.getConfig(); if (configResult.isFailure) { From 9110af80d8e4b0bc0ef4aeaa99e9eae88eb2b5bf Mon Sep 17 00:00:00 2001 From: Nora Date: Fri, 2 Dec 2022 17:41:46 +0100 Subject: [PATCH 2/7] Add test --- .../src/databases/db-item-selection.ts | 40 ++++ extensions/ql-vscode/src/databases/db-item.ts | 32 --- .../ql-vscode/src/databases/db-manager.ts | 3 +- .../databases/db-item-selection.test.ts | 215 ++++++++++++++++++ 4 files changed, 257 insertions(+), 33 deletions(-) create mode 100644 extensions/ql-vscode/src/databases/db-item-selection.ts create mode 100644 extensions/ql-vscode/test/pure-tests/databases/db-item-selection.test.ts diff --git a/extensions/ql-vscode/src/databases/db-item-selection.ts b/extensions/ql-vscode/src/databases/db-item-selection.ts new file mode 100644 index 00000000000..c38eb53fa1a --- /dev/null +++ b/extensions/ql-vscode/src/databases/db-item-selection.ts @@ -0,0 +1,40 @@ +import { DbItem, DbItemKind } from "./db-item"; + +export function getSelectedDbItem(dbItems: DbItem[]): DbItem | undefined { + for (const dbItem of dbItems) { + if ( + dbItem.kind === DbItemKind.RootRemote || + dbItem.kind === DbItemKind.RootLocal + ) { + for (const child of dbItem.children) { + switch (child.kind) { + case DbItemKind.LocalList: + if (child.selected) { + return child; + } + for (const database of child.databases) { + if (database.selected) { + return database; + } + } + break; + case DbItemKind.RemoteUserDefinedList: + if (child.selected) { + return child; + } + for (const repo of child.repos) { + if (repo.selected) { + return repo; + } + } + break; + default: + if (child.selected) { + return child; + } + } + } + } + } + return undefined; +} diff --git a/extensions/ql-vscode/src/databases/db-item.ts b/extensions/ql-vscode/src/databases/db-item.ts index d56f6cb7067..76bda03c6bc 100644 --- a/extensions/ql-vscode/src/databases/db-item.ts +++ b/extensions/ql-vscode/src/databases/db-item.ts @@ -124,35 +124,3 @@ const SelectableDbItemKinds = [ DbItemKind.RemoteOwner, DbItemKind.RemoteRepo, ]; - -export function getSelectedDbItem(dbItems: DbItem[]): DbItem | undefined { - for (const dbItem of dbItems) { - if ( - dbItem.kind === DbItemKind.RootRemote || - dbItem.kind === DbItemKind.RootLocal - ) { - for (const child of dbItem.children) { - switch (child.kind) { - case DbItemKind.LocalList: - for (const database of child.databases) { - if (database.selected) { - return database; - } - } - break; - case DbItemKind.RemoteUserDefinedList: - for (const repo of child.repos) { - if (repo.selected) { - return repo; - } - } - break; - default: - if (child.selected) { - return child; - } - } - } - } - } -} diff --git a/extensions/ql-vscode/src/databases/db-manager.ts b/extensions/ql-vscode/src/databases/db-manager.ts index a3395f3b795..405303bf021 100644 --- a/extensions/ql-vscode/src/databases/db-manager.ts +++ b/extensions/ql-vscode/src/databases/db-manager.ts @@ -2,7 +2,8 @@ import { App } from "../common/app"; import { AppEvent, AppEventEmitter } from "../common/events"; import { ValueResult } from "../common/value-result"; import { DbConfigStore } from "./config/db-config-store"; -import { DbItem, getSelectedDbItem } from "./db-item"; +import { DbItem } from "./db-item"; +import { getSelectedDbItem } from "./db-item-selection"; import { createLocalTree, createRemoteTree } from "./db-tree-creator"; export class DbManager { diff --git a/extensions/ql-vscode/test/pure-tests/databases/db-item-selection.test.ts b/extensions/ql-vscode/test/pure-tests/databases/db-item-selection.test.ts new file mode 100644 index 00000000000..61c5bef9e49 --- /dev/null +++ b/extensions/ql-vscode/test/pure-tests/databases/db-item-selection.test.ts @@ -0,0 +1,215 @@ +import { DbItem, DbItemKind } from "../../../src/databases/db-item"; +import { getSelectedDbItem } from "../../../src/databases/db-item-selection"; +describe("db item selection", () => { + it("return undefined if no item is selected", () => { + const dbItems: DbItem[] = [ + { + kind: DbItemKind.RootRemote, + children: [ + { + kind: DbItemKind.RemoteSystemDefinedList, + listName: "top_10", + listDisplayName: "Top 10 repositories", + listDescription: "Top 10 repositories of a language", + selected: false, + }, + { + kind: DbItemKind.RemoteSystemDefinedList, + listName: "top_100", + listDisplayName: "Top 100 repositories", + listDescription: "Top 100 repositories of a language", + selected: false, + }, + { + kind: DbItemKind.RemoteSystemDefinedList, + listName: "top_1000", + listDisplayName: "Top 1000 repositories", + listDescription: "Top 1000 repositories of a language", + selected: false, + }, + { + kind: DbItemKind.RemoteOwner, + ownerName: "github", + selected: false, + }, + { + kind: DbItemKind.RemoteUserDefinedList, + listName: "my list", + repos: [ + { + kind: DbItemKind.RemoteRepo, + repoFullName: "owner1/repo2", + selected: false, + }, + { + kind: DbItemKind.RemoteRepo, + repoFullName: "owner1/repo3", + selected: false, + }, + ], + selected: false, + }, + ], + }, + { + kind: DbItemKind.RootLocal, + children: [ + { + kind: DbItemKind.LocalList, + listName: "list-1", + databases: [ + { + kind: DbItemKind.LocalDatabase, + databaseName: "db1", + dateAdded: 1234, + language: "javascript", + storagePath: "/foo/bar", + selected: false, + }, + { + kind: DbItemKind.LocalDatabase, + databaseName: "db2", + dateAdded: 1234, + language: "javascript", + storagePath: "/foo/bar", + selected: false, + }, + ], + selected: false, + }, + { + kind: DbItemKind.LocalDatabase, + databaseName: "db3", + dateAdded: 1234, + language: "javascript", + storagePath: "/foo/bar", + selected: false, + }, + ], + }, + ]; + + expect(getSelectedDbItem(dbItems)).toBeUndefined(); + }); + + it("return correct local database item from DbItem list", () => { + const dbItems: DbItem[] = [ + { + kind: DbItemKind.RootLocal, + children: [ + { + kind: DbItemKind.LocalList, + listName: "list-1", + databases: [ + { + kind: DbItemKind.LocalDatabase, + databaseName: "db1", + dateAdded: 1234, + language: "javascript", + storagePath: "/foo/bar", + selected: false, + }, + { + kind: DbItemKind.LocalDatabase, + databaseName: "db2", + dateAdded: 1234, + language: "javascript", + storagePath: "/foo/bar", + selected: true, + }, + ], + selected: false, + }, + { + kind: DbItemKind.LocalDatabase, + databaseName: "db3", + dateAdded: 1234, + language: "javascript", + storagePath: "/foo/bar", + selected: false, + }, + ], + }, + ]; + + expect(getSelectedDbItem(dbItems)).toEqual({ + kind: DbItemKind.LocalDatabase, + databaseName: "db2", + dateAdded: 1234, + language: "javascript", + storagePath: "/foo/bar", + selected: true, + }); + }); + + it("return correct remote database list item from DbItem list", () => { + const dbItems: DbItem[] = [ + { + kind: DbItemKind.RootRemote, + children: [ + { + kind: DbItemKind.RemoteSystemDefinedList, + listName: "top_10", + listDisplayName: "Top 10 repositories", + listDescription: "Top 10 repositories of a language", + selected: false, + }, + { + kind: DbItemKind.RemoteSystemDefinedList, + listName: "top_100", + listDisplayName: "Top 100 repositories", + listDescription: "Top 100 repositories of a language", + selected: false, + }, + { + kind: DbItemKind.RemoteSystemDefinedList, + listName: "top_1000", + listDisplayName: "Top 1000 repositories", + listDescription: "Top 1000 repositories of a language", + selected: false, + }, + { + kind: DbItemKind.RemoteOwner, + ownerName: "github", + selected: false, + }, + { + kind: DbItemKind.RemoteUserDefinedList, + listName: "my list", + repos: [ + { + kind: DbItemKind.RemoteRepo, + repoFullName: "owner1/repo2", + selected: false, + }, + { + kind: DbItemKind.RemoteRepo, + repoFullName: "owner1/repo3", + selected: false, + }, + ], + selected: true, + }, + ], + }, + ]; + + expect(getSelectedDbItem(dbItems)).toEqual({ + kind: DbItemKind.RemoteUserDefinedList, + listName: "my list", + repos: [ + { + kind: DbItemKind.RemoteRepo, + repoFullName: "owner1/repo2", + selected: false, + }, + { + kind: DbItemKind.RemoteRepo, + repoFullName: "owner1/repo3", + selected: false, + }, + ], + selected: true, + }); + }); +}); From 60b1f141a11893f30f4260fb9e26e2cfa9dd540b Mon Sep 17 00:00:00 2001 From: Nora Date: Mon, 5 Dec 2022 16:20:49 +0100 Subject: [PATCH 3/7] Rename and reduce test lines --- .../databases/db-item-selection.test.ts | 27 +++---------------- 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/extensions/ql-vscode/test/pure-tests/databases/db-item-selection.test.ts b/extensions/ql-vscode/test/pure-tests/databases/db-item-selection.test.ts index 61c5bef9e49..590d5f4ae77 100644 --- a/extensions/ql-vscode/test/pure-tests/databases/db-item-selection.test.ts +++ b/extensions/ql-vscode/test/pure-tests/databases/db-item-selection.test.ts @@ -1,7 +1,7 @@ import { DbItem, DbItemKind } from "../../../src/databases/db-item"; import { getSelectedDbItem } from "../../../src/databases/db-item-selection"; describe("db item selection", () => { - it("return undefined if no item is selected", () => { + it("dhoulf return undefined if no item is selected", () => { const dbItems: DbItem[] = [ { kind: DbItemKind.RootRemote, @@ -20,13 +20,6 @@ describe("db item selection", () => { listDescription: "Top 100 repositories of a language", selected: false, }, - { - kind: DbItemKind.RemoteSystemDefinedList, - listName: "top_1000", - listDisplayName: "Top 1000 repositories", - listDescription: "Top 1000 repositories of a language", - selected: false, - }, { kind: DbItemKind.RemoteOwner, ownerName: "github", @@ -92,7 +85,7 @@ describe("db item selection", () => { expect(getSelectedDbItem(dbItems)).toBeUndefined(); }); - it("return correct local database item from DbItem list", () => { + it("should return correct local database item from DbItem list", () => { const dbItems: DbItem[] = [ { kind: DbItemKind.RootLocal, @@ -142,7 +135,7 @@ describe("db item selection", () => { }); }); - it("return correct remote database list item from DbItem list", () => { + it("should return correct remote database list item from DbItem list", () => { const dbItems: DbItem[] = [ { kind: DbItemKind.RootRemote, @@ -154,20 +147,6 @@ describe("db item selection", () => { listDescription: "Top 10 repositories of a language", selected: false, }, - { - kind: DbItemKind.RemoteSystemDefinedList, - listName: "top_100", - listDisplayName: "Top 100 repositories", - listDescription: "Top 100 repositories of a language", - selected: false, - }, - { - kind: DbItemKind.RemoteSystemDefinedList, - listName: "top_1000", - listDisplayName: "Top 1000 repositories", - listDescription: "Top 1000 repositories of a language", - selected: false, - }, { kind: DbItemKind.RemoteOwner, ownerName: "github", From 9362881e227ce99b1b6561d522208d48f79d866a Mon Sep 17 00:00:00 2001 From: Nora Date: Mon, 5 Dec 2022 16:21:03 +0100 Subject: [PATCH 4/7] Rename method on db Manager --- extensions/ql-vscode/src/databases/db-manager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/ql-vscode/src/databases/db-manager.ts b/extensions/ql-vscode/src/databases/db-manager.ts index 405303bf021..a4d499a82fc 100644 --- a/extensions/ql-vscode/src/databases/db-manager.ts +++ b/extensions/ql-vscode/src/databases/db-manager.ts @@ -19,7 +19,7 @@ export class DbManager { }); } - public selectedDbItem(): DbItem | undefined { + public getSelectedDbItem(): DbItem | undefined { const dbItems = this.getDbItems(); if (dbItems.isFailure) { From 7a2f9761994bdbbceb7a1ca8305a1e2ab4946a0e Mon Sep 17 00:00:00 2001 From: Nora Date: Mon, 5 Dec 2022 16:21:35 +0100 Subject: [PATCH 5/7] Refactor selection method to allow all types of DbItem lists --- .../src/databases/db-item-selection.ts | 58 ++++++++++--------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/extensions/ql-vscode/src/databases/db-item-selection.ts b/extensions/ql-vscode/src/databases/db-item-selection.ts index c38eb53fa1a..9ddc9bdc8ac 100644 --- a/extensions/ql-vscode/src/databases/db-item-selection.ts +++ b/extensions/ql-vscode/src/databases/db-item-selection.ts @@ -1,4 +1,4 @@ -import { DbItem, DbItemKind } from "./db-item"; +import { DbItem, DbItemKind, LocalDbItem, RemoteDbItem } from "./db-item"; export function getSelectedDbItem(dbItems: DbItem[]): DbItem | undefined { for (const dbItem of dbItems) { @@ -7,34 +7,38 @@ export function getSelectedDbItem(dbItems: DbItem[]): DbItem | undefined { dbItem.kind === DbItemKind.RootLocal ) { for (const child of dbItem.children) { - switch (child.kind) { - case DbItemKind.LocalList: - if (child.selected) { - return child; - } - for (const database of child.databases) { - if (database.selected) { - return database; - } - } - break; - case DbItemKind.RemoteUserDefinedList: - if (child.selected) { - return child; - } - for (const repo of child.repos) { - if (repo.selected) { - return repo; - } - } - break; - default: - if (child.selected) { - return child; - } - } + const selectedItem = extractSelected(child); + if (selectedItem) return selectedItem; } + } else { + const selectedItem = extractSelected(dbItem); + if (selectedItem) return selectedItem; } } return undefined; } + +function extractSelected( + dbItem: RemoteDbItem | LocalDbItem, +): DbItem | undefined { + if (dbItem.selected) { + return dbItem; + } + switch (dbItem.kind) { + case DbItemKind.LocalList: + for (const database of dbItem.databases) { + if (database.selected) { + return database; + } + } + break; + case DbItemKind.RemoteUserDefinedList: + for (const repo of dbItem.repos) { + if (repo.selected) { + return repo; + } + } + break; + } + return undefined; +} From 1050968db17e8fc371329763e00c1f69668a11ec Mon Sep 17 00:00:00 2001 From: Nora Date: Mon, 5 Dec 2022 16:57:30 +0100 Subject: [PATCH 6/7] Update extensions/ql-vscode/test/pure-tests/databases/db-item-selection.test.ts Co-authored-by: Charis Kyriakou --- .../test/pure-tests/databases/db-item-selection.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/ql-vscode/test/pure-tests/databases/db-item-selection.test.ts b/extensions/ql-vscode/test/pure-tests/databases/db-item-selection.test.ts index 590d5f4ae77..0844f855403 100644 --- a/extensions/ql-vscode/test/pure-tests/databases/db-item-selection.test.ts +++ b/extensions/ql-vscode/test/pure-tests/databases/db-item-selection.test.ts @@ -1,7 +1,7 @@ import { DbItem, DbItemKind } from "../../../src/databases/db-item"; import { getSelectedDbItem } from "../../../src/databases/db-item-selection"; describe("db item selection", () => { - it("dhoulf return undefined if no item is selected", () => { + it("should return undefined if no item is selected", () => { const dbItems: DbItem[] = [ { kind: DbItemKind.RootRemote, From 425befa959f62508174c2eac51f529c6fa546838 Mon Sep 17 00:00:00 2001 From: Nora Date: Mon, 5 Dec 2022 17:38:40 +0100 Subject: [PATCH 7/7] Add tests --- .../databases/db-item-selection.test.ts | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/extensions/ql-vscode/test/pure-tests/databases/db-item-selection.test.ts b/extensions/ql-vscode/test/pure-tests/databases/db-item-selection.test.ts index 0844f855403..b41e5553359 100644 --- a/extensions/ql-vscode/test/pure-tests/databases/db-item-selection.test.ts +++ b/extensions/ql-vscode/test/pure-tests/databases/db-item-selection.test.ts @@ -191,4 +191,88 @@ describe("db item selection", () => { selected: true, }); }); + + it("should handle arbitrary list of db items", () => { + const dbItems: DbItem[] = [ + { + kind: DbItemKind.RootRemote, + children: [ + { + kind: DbItemKind.RemoteSystemDefinedList, + listName: "top_10", + listDisplayName: "Top 10 repositories", + listDescription: "Top 10 repositories of a language", + selected: false, + }, + { + kind: DbItemKind.RemoteOwner, + ownerName: "github", + selected: false, + }, + { + kind: DbItemKind.RemoteUserDefinedList, + listName: "my list", + repos: [ + { + kind: DbItemKind.RemoteRepo, + repoFullName: "owner1/repo2", + selected: false, + }, + { + kind: DbItemKind.RemoteRepo, + repoFullName: "owner1/repo3", + selected: false, + }, + ], + selected: false, + }, + ], + }, + { + kind: DbItemKind.RemoteSystemDefinedList, + listName: "top_10", + listDisplayName: "Top 10 repositories", + listDescription: "Top 10 repositories of a language", + selected: true, + }, + ]; + + expect(getSelectedDbItem(dbItems)).toEqual({ + kind: DbItemKind.RemoteSystemDefinedList, + listName: "top_10", + listDisplayName: "Top 10 repositories", + listDescription: "Top 10 repositories of a language", + selected: true, + }); + }); + + it("should handle empty db item lists", () => { + const dbItems: DbItem[] = [ + { + kind: DbItemKind.RootRemote, + children: [ + { + kind: DbItemKind.RemoteSystemDefinedList, + listName: "top_10", + listDisplayName: "Top 10 repositories", + listDescription: "Top 10 repositories of a language", + selected: false, + }, + { + kind: DbItemKind.RemoteOwner, + ownerName: "github", + selected: false, + }, + { + kind: DbItemKind.RemoteUserDefinedList, + listName: "my list", + repos: [], + selected: false, + }, + ], + }, + ]; + + expect(getSelectedDbItem(dbItems)).toBeUndefined(); + }); });