Only update the details view when data has changed

This commit is contained in:
Robert
2023-08-14 15:35:21 +01:00
parent a46209b22d
commit 4e70c8999f
2 changed files with 83 additions and 6 deletions

View File

@@ -34,17 +34,28 @@ export class ModelDetailsDataProvider
return this.onDidChangeTreeDataEmitter.event;
}
/**
* Update the data displayed in the tree view.
*
* Will only trigger an update if the data has changed. This relies on
* object identity, so be sure to not mutate the data passed to this
* method and instead always pass new objects/arrays.
*/
public async setState(
externalApiUsages: ExternalApiUsage[],
databaseItem: DatabaseItem,
): Promise<void> {
if (
this.externalApiUsages !== externalApiUsages ||
this.databaseItem !== databaseItem
) {
this.externalApiUsages = externalApiUsages;
this.databaseItem = databaseItem;
this.sourceLocationPrefix = await this.databaseItem.getSourceLocationPrefix(
this.cliServer,
);
this.sourceLocationPrefix =
await this.databaseItem.getSourceLocationPrefix(this.cliServer);
this.onDidChangeTreeDataEmitter.fire();
}
}
getTreeItem(item: ModelDetailsTreeViewItem): TreeItem {
if (isExternalApiUsage(item)) {

View File

@@ -0,0 +1,66 @@
import { CodeQLCliServer } from "../../../../../src/codeql-cli/cli";
import { ExternalApiUsage } from "../../../../../src/data-extensions-editor/external-api-usage";
import { ModelDetailsDataProvider } from "../../../../../src/data-extensions-editor/model-details/model-details-data-provider";
import { DatabaseItem } from "../../../../../src/databases/local-databases";
import { mockedObject } from "../../../utils/mocking.helpers";
describe("ModelDetailsDataProvider", () => {
const mockCliServer = mockedObject<CodeQLCliServer>({});
describe("setState", () => {
it("should emit onDidChangeTreeData event when state has changed", async () => {
const externalApiUsages: ExternalApiUsage[] = [];
const dbItem = mockedObject<DatabaseItem>({
getSourceLocationPrefix: () => "test",
});
const dataProvider = new ModelDetailsDataProvider(mockCliServer);
await dataProvider.setState(externalApiUsages, dbItem);
const onDidChangeTreeDataListener = jest.fn();
dataProvider.onDidChangeTreeData(onDidChangeTreeDataListener);
await dataProvider.setState(externalApiUsages, dbItem);
expect(onDidChangeTreeDataListener).toHaveBeenCalledTimes(0);
});
it("should emit onDidChangeTreeData event when externalApiUsages has changed", async () => {
const externalApiUsages1: ExternalApiUsage[] = [];
const externalApiUsages2: ExternalApiUsage[] = [];
const dbItem = mockedObject<DatabaseItem>({
getSourceLocationPrefix: () => "test",
});
const dataProvider = new ModelDetailsDataProvider(mockCliServer);
await dataProvider.setState(externalApiUsages1, dbItem);
const onDidChangeTreeDataListener = jest.fn();
dataProvider.onDidChangeTreeData(onDidChangeTreeDataListener);
await dataProvider.setState(externalApiUsages2, dbItem);
expect(onDidChangeTreeDataListener).toHaveBeenCalledTimes(1);
});
it("should emit onDidChangeTreeData event when dbItem has changed", async () => {
const externalApiUsages: ExternalApiUsage[] = [];
const dbItem1 = mockedObject<DatabaseItem>({
getSourceLocationPrefix: () => "test",
});
const dbItem2 = mockedObject<DatabaseItem>({
getSourceLocationPrefix: () => "test",
});
const dataProvider = new ModelDetailsDataProvider(mockCliServer);
await dataProvider.setState(externalApiUsages, dbItem1);
const onDidChangeTreeDataListener = jest.fn();
dataProvider.onDidChangeTreeData(onDidChangeTreeDataListener);
await dataProvider.setState(externalApiUsages, dbItem2);
expect(onDidChangeTreeDataListener).toHaveBeenCalledTimes(1);
});
});
});