Skip to content

Commit cddf078

Browse files
Merge branch 'main' into dependabot/npm_and_yarn/extensions/ql-vscode/typescript-eslint-7954a73ad2
2 parents bfa7ea1 + 8326ef3 commit cddf078

File tree

9 files changed

+353
-166
lines changed

9 files changed

+353
-166
lines changed

extensions/ql-vscode/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## [UNRELEASED]
44

5+
- Update results view to display the length of the shortest path for path queries. [#3687](https://github.com/github/vscode-codeql/pull/3687)
6+
57
## 1.14.0 - 7 August 2024
68

79
- Add Python support to the CodeQL Model Editor. [#3676](https://github.com/github/vscode-codeql/pull/3676)

extensions/ql-vscode/package-lock.json

Lines changed: 151 additions & 151 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extensions/ql-vscode/package.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2011,18 +2011,18 @@
20112011
"@faker-js/faker": "^8.4.1",
20122012
"@github/markdownlint-github": "^0.6.2",
20132013
"@playwright/test": "^1.40.1",
2014-
"@storybook/addon-a11y": "^8.2.7",
2015-
"@storybook/addon-actions": "^8.2.7",
2016-
"@storybook/addon-essentials": "^8.2.7",
2017-
"@storybook/addon-interactions": "^8.2.7",
2018-
"@storybook/addon-links": "^8.2.7",
2014+
"@storybook/addon-a11y": "^8.2.8",
2015+
"@storybook/addon-actions": "^8.2.8",
2016+
"@storybook/addon-essentials": "^8.2.8",
2017+
"@storybook/addon-interactions": "^8.2.8",
2018+
"@storybook/addon-links": "^8.2.8",
20192019
"@storybook/blocks": "^8.0.2",
2020-
"@storybook/components": "^8.2.7",
2020+
"@storybook/components": "^8.2.8",
20212021
"@storybook/csf": "^0.1.11",
20222022
"@storybook/icons": "^1.2.10",
2023-
"@storybook/manager-api": "^8.2.7",
2024-
"@storybook/react": "^8.2.7",
2025-
"@storybook/react-vite": "^8.2.7",
2023+
"@storybook/manager-api": "^8.2.8",
2024+
"@storybook/react": "^8.2.8",
2025+
"@storybook/react-vite": "^8.2.8",
20262026
"@storybook/theming": "^8.2.4",
20272027
"@testing-library/dom": "^10.4.0",
20282028
"@testing-library/jest-dom": "^6.4.8",
@@ -2087,7 +2087,7 @@
20872087
"npm-run-all": "^4.1.5",
20882088
"patch-package": "^8.0.0",
20892089
"prettier": "^3.2.5",
2090-
"storybook": "^8.2.7",
2090+
"storybook": "^8.2.8",
20912091
"tar-stream": "^3.1.7",
20922092
"through2": "^4.0.2",
20932093
"ts-jest": "^29.1.4",

extensions/ql-vscode/src/view/results/AlertTablePathRow.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ import { AlertTableDropdownIndicatorCell } from "./AlertTableDropdownIndicatorCe
1111
import { useCallback, useMemo } from "react";
1212
import { VerticalRule } from "../common/VerticalRule";
1313
import type { UserSettings } from "../../common/interface-types";
14+
import { pluralize } from "../../common/word";
1415

15-
interface Props {
16+
export interface Props {
1617
path: ThreadFlow;
1718
pathIndex: number;
1819
resultIndex: number;
@@ -65,7 +66,7 @@ export function AlertTablePathRow(props: Props) {
6566
onClick={handleDropdownClick}
6667
/>
6768
<td className="vscode-codeql__text-center" colSpan={4}>
68-
Path
69+
{`Path (${pluralize(path.locations.length, "step", "steps")})`}
6970
</td>
7071
</tr>
7172
{currentPathExpanded &&

extensions/ql-vscode/src/view/results/AlertTableResultRow.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ import { SarifLocation } from "./locations/SarifLocation";
1313
import { SarifMessageWithLocations } from "./locations/SarifMessageWithLocations";
1414
import { AlertTablePathRow } from "./AlertTablePathRow";
1515
import type { UserSettings } from "../../common/interface-types";
16+
import { VSCodeBadge } from "@vscode/webview-ui-toolkit/react";
1617

17-
interface Props {
18+
export interface Props {
1819
result: Result;
1920
resultIndex: number;
2021
expanded: Set<string>;
@@ -83,6 +84,11 @@ export function AlertTableResultRow(props: Props) {
8384
/>
8485
);
8586

87+
const allPaths = getAllPaths(result);
88+
const shortestPath = Math.min(
89+
...allPaths.map((path) => path.locations.length),
90+
);
91+
8692
const currentResultExpanded = expanded.has(keyToString(resultKey));
8793
return (
8894
<>
@@ -102,6 +108,9 @@ export function AlertTableResultRow(props: Props) {
102108
onClick={handleDropdownClick}
103109
/>
104110
<td className="vscode-codeql__icon-cell">{listUnordered}</td>
111+
<td className="vscode-codeql__icon-cell">
112+
<VSCodeBadge title="Shortest path">{shortestPath}</VSCodeBadge>
113+
</td>
105114
<td colSpan={3}>{msg}</td>
106115
</>
107116
)}
@@ -118,7 +127,7 @@ export function AlertTableResultRow(props: Props) {
118127
</tr>
119128
{currentResultExpanded &&
120129
result.codeFlows &&
121-
getAllPaths(result).map((path, pathIndex) => (
130+
allPaths.map((path, pathIndex) => (
122131
<AlertTablePathRow
123132
key={`${resultIndex}-${pathIndex}`}
124133
{...props}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { render as reactRender, screen } from "@testing-library/react";
2+
import type { Props } from "../AlertTablePathRow";
3+
import { AlertTablePathRow } from "../AlertTablePathRow";
4+
import { createMockResults } from "../../../../test/factories/results/mockresults";
5+
6+
describe(AlertTablePathRow.name, () => {
7+
const render = (props?: Props) => {
8+
const mockRef = { current: null } as React.RefObject<HTMLTableRowElement>;
9+
const results = createMockResults();
10+
const threadFlow = results[0]?.codeFlows?.[0]?.threadFlows?.[0];
11+
12+
if (!threadFlow) {
13+
throw new Error("ThreadFlow is undefined");
14+
}
15+
reactRender(
16+
<AlertTablePathRow
17+
resultIndex={1}
18+
selectedItem={undefined}
19+
selectedItemRef={mockRef}
20+
path={threadFlow}
21+
pathIndex={0}
22+
currentPathExpanded={true}
23+
databaseUri={"dbUri"}
24+
sourceLocationPrefix="src"
25+
userSettings={{ shouldShowProvenance: false }}
26+
updateSelectionCallback={jest.fn()}
27+
toggleExpanded={jest.fn()}
28+
{...props}
29+
/>,
30+
);
31+
};
32+
33+
it("renders number of steps", () => {
34+
render();
35+
36+
expect(screen.getByText("Path (3 steps)")).toBeInTheDocument();
37+
});
38+
});
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { render as reactRender, screen } from "@testing-library/react";
2+
import { AlertTableResultRow } from "../AlertTableResultRow";
3+
import type { Props } from "../AlertTableResultRow";
4+
import { createMockResults } from "../../../../test/factories/results/mockresults";
5+
6+
describe(AlertTableResultRow.name, () => {
7+
const render = (props?: Props) => {
8+
const mockRef = { current: null } as React.RefObject<HTMLTableRowElement>;
9+
const results = createMockResults();
10+
11+
reactRender(
12+
<AlertTableResultRow
13+
result={results[0]}
14+
expanded={new Set()}
15+
resultIndex={1}
16+
selectedItem={undefined}
17+
selectedItemRef={mockRef}
18+
databaseUri={"dbUri"}
19+
sourceLocationPrefix="src"
20+
userSettings={{ shouldShowProvenance: false }}
21+
updateSelectionCallback={jest.fn()}
22+
toggleExpanded={jest.fn()}
23+
{...props}
24+
/>,
25+
);
26+
};
27+
28+
it("renders shortest path badge", () => {
29+
render();
30+
31+
expect(screen.getByTitle("Shortest path")).toHaveTextContent("3");
32+
});
33+
});

extensions/ql-vscode/supported_cli_versions.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[
2-
"v2.18.1",
2+
"v2.18.2",
33
"v2.17.6",
44
"v2.16.6",
55
"v2.15.5",
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import type { Result } from "sarif";
2+
3+
export function createMockResults(): Result[] {
4+
return [
5+
{
6+
ruleId: "java/sql-injection",
7+
ruleIndex: 0,
8+
rule: { id: "java/sql-injection", index: 0 },
9+
message: {
10+
text: "This query depends on a [user-provided value](1).",
11+
},
12+
locations: [
13+
{
14+
physicalLocation: {
15+
artifactLocation: {
16+
uri: "src/main/java/org/example/HelloController.java",
17+
uriBaseId: "%SRCROOT%",
18+
index: 0,
19+
},
20+
region: { startLine: 15, startColumn: 29, endColumn: 56 },
21+
},
22+
},
23+
],
24+
partialFingerprints: {
25+
primaryLocationLineHash: "87e2d3cc5b365094:1",
26+
primaryLocationStartColumnFingerprint: "16",
27+
},
28+
codeFlows: [
29+
{
30+
threadFlows: [
31+
{
32+
locations: [
33+
{
34+
location: {
35+
physicalLocation: {
36+
artifactLocation: {
37+
uri: "src/main/java/org/example/HelloController.java",
38+
uriBaseId: "%SRCROOT%",
39+
index: 0,
40+
},
41+
region: {
42+
startLine: 13,
43+
startColumn: 25,
44+
endColumn: 54,
45+
},
46+
},
47+
message: { text: "id : String" },
48+
},
49+
},
50+
{
51+
location: {
52+
physicalLocation: {
53+
artifactLocation: {
54+
uri: "file:/",
55+
index: 5,
56+
},
57+
region: {
58+
startLine: 13,
59+
startColumn: 25,
60+
endColumn: 54,
61+
},
62+
},
63+
message: { text: "id : String" },
64+
},
65+
},
66+
{
67+
location: {
68+
physicalLocation: {
69+
artifactLocation: {
70+
uri: "src/main/java/org/example/HelloController.java",
71+
uriBaseId: "%SRCROOT%",
72+
index: 0,
73+
},
74+
region: {
75+
startLine: 15,
76+
startColumn: 29,
77+
endColumn: 56,
78+
},
79+
},
80+
message: { text: "... + ..." },
81+
},
82+
},
83+
],
84+
},
85+
],
86+
},
87+
],
88+
relatedLocations: [
89+
{
90+
id: 1,
91+
physicalLocation: {
92+
artifactLocation: {
93+
uri: "src/main/java/org/example/HelloController.java",
94+
uriBaseId: "%SRCROOT%",
95+
index: 0,
96+
},
97+
region: { startLine: 13, startColumn: 25, endColumn: 54 },
98+
},
99+
message: { text: "user-provided value" },
100+
},
101+
],
102+
},
103+
];
104+
}

0 commit comments

Comments
 (0)