Skip to content

Commit 4e70c89

Browse files
Only update the details view when data has changed
1 parent a46209b commit 4e70c89

2 files changed

Lines changed: 83 additions & 6 deletions

File tree

extensions/ql-vscode/src/data-extensions-editor/model-details/model-details-data-provider.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,27 @@ export class ModelDetailsDataProvider
3434
return this.onDidChangeTreeDataEmitter.event;
3535
}
3636

37+
/**
38+
* Update the data displayed in the tree view.
39+
*
40+
* Will only trigger an update if the data has changed. This relies on
41+
* object identity, so be sure to not mutate the data passed to this
42+
* method and instead always pass new objects/arrays.
43+
*/
3744
public async setState(
3845
externalApiUsages: ExternalApiUsage[],
3946
databaseItem: DatabaseItem,
4047
): Promise<void> {
41-
this.externalApiUsages = externalApiUsages;
42-
this.databaseItem = databaseItem;
43-
this.sourceLocationPrefix = await this.databaseItem.getSourceLocationPrefix(
44-
this.cliServer,
45-
);
46-
this.onDidChangeTreeDataEmitter.fire();
48+
if (
49+
this.externalApiUsages !== externalApiUsages ||
50+
this.databaseItem !== databaseItem
51+
) {
52+
this.externalApiUsages = externalApiUsages;
53+
this.databaseItem = databaseItem;
54+
this.sourceLocationPrefix =
55+
await this.databaseItem.getSourceLocationPrefix(this.cliServer);
56+
this.onDidChangeTreeDataEmitter.fire();
57+
}
4758
}
4859

4960
getTreeItem(item: ModelDetailsTreeViewItem): TreeItem {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { CodeQLCliServer } from "../../../../../src/codeql-cli/cli";
2+
import { ExternalApiUsage } from "../../../../../src/data-extensions-editor/external-api-usage";
3+
import { ModelDetailsDataProvider } from "../../../../../src/data-extensions-editor/model-details/model-details-data-provider";
4+
import { DatabaseItem } from "../../../../../src/databases/local-databases";
5+
import { mockedObject } from "../../../utils/mocking.helpers";
6+
7+
describe("ModelDetailsDataProvider", () => {
8+
const mockCliServer = mockedObject<CodeQLCliServer>({});
9+
10+
describe("setState", () => {
11+
it("should emit onDidChangeTreeData event when state has changed", async () => {
12+
const externalApiUsages: ExternalApiUsage[] = [];
13+
const dbItem = mockedObject<DatabaseItem>({
14+
getSourceLocationPrefix: () => "test",
15+
});
16+
17+
const dataProvider = new ModelDetailsDataProvider(mockCliServer);
18+
await dataProvider.setState(externalApiUsages, dbItem);
19+
20+
const onDidChangeTreeDataListener = jest.fn();
21+
dataProvider.onDidChangeTreeData(onDidChangeTreeDataListener);
22+
23+
await dataProvider.setState(externalApiUsages, dbItem);
24+
25+
expect(onDidChangeTreeDataListener).toHaveBeenCalledTimes(0);
26+
});
27+
28+
it("should emit onDidChangeTreeData event when externalApiUsages has changed", async () => {
29+
const externalApiUsages1: ExternalApiUsage[] = [];
30+
const externalApiUsages2: ExternalApiUsage[] = [];
31+
const dbItem = mockedObject<DatabaseItem>({
32+
getSourceLocationPrefix: () => "test",
33+
});
34+
35+
const dataProvider = new ModelDetailsDataProvider(mockCliServer);
36+
await dataProvider.setState(externalApiUsages1, dbItem);
37+
38+
const onDidChangeTreeDataListener = jest.fn();
39+
dataProvider.onDidChangeTreeData(onDidChangeTreeDataListener);
40+
41+
await dataProvider.setState(externalApiUsages2, dbItem);
42+
43+
expect(onDidChangeTreeDataListener).toHaveBeenCalledTimes(1);
44+
});
45+
46+
it("should emit onDidChangeTreeData event when dbItem has changed", async () => {
47+
const externalApiUsages: ExternalApiUsage[] = [];
48+
const dbItem1 = mockedObject<DatabaseItem>({
49+
getSourceLocationPrefix: () => "test",
50+
});
51+
const dbItem2 = mockedObject<DatabaseItem>({
52+
getSourceLocationPrefix: () => "test",
53+
});
54+
55+
const dataProvider = new ModelDetailsDataProvider(mockCliServer);
56+
await dataProvider.setState(externalApiUsages, dbItem1);
57+
58+
const onDidChangeTreeDataListener = jest.fn();
59+
dataProvider.onDidChangeTreeData(onDidChangeTreeDataListener);
60+
61+
await dataProvider.setState(externalApiUsages, dbItem2);
62+
63+
expect(onDidChangeTreeDataListener).toHaveBeenCalledTimes(1);
64+
});
65+
});
66+
});

0 commit comments

Comments
 (0)