Skip to content

Commit 9bd9981

Browse files
authored
Create insta snapshot for SARIF output (#13345)
## Summary Follow-up from #13268, this PR updates the test case to use `assert_snapshot` now that the output is limited to only include the rules with diagnostics. ## Test Plan `cargo insta test`
1 parent 21bfab9 commit 9bd9981

File tree

4 files changed

+271
-27
lines changed

4 files changed

+271
-27
lines changed

Cargo.lock

+118
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ruff_linter/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ unicode-normalization = { workspace = true }
7373
url = { workspace = true }
7474

7575
[dev-dependencies]
76-
insta = { workspace = true }
76+
insta = { workspace = true, features = ["filters", "json", "redactions"] }
7777
test-case = { workspace = true }
7878
# Disable colored output in tests
7979
colored = { workspace = true, features = ["no-color"] }

crates/ruff_linter/src/message/sarif.rs

+6-26
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,6 @@ impl Serialize for SarifResult {
186186

187187
#[cfg(test)]
188188
mod tests {
189-
190189
use crate::message::tests::{
191190
capture_emitter_output, create_messages, create_syntax_error_messages,
192191
};
@@ -213,30 +212,11 @@ mod tests {
213212
#[test]
214213
fn test_results() {
215214
let content = get_output();
216-
let sarif = serde_json::from_str::<serde_json::Value>(content.as_str()).unwrap();
217-
let rules = sarif["runs"][0]["tool"]["driver"]["rules"]
218-
.as_array()
219-
.unwrap();
220-
let results = sarif["runs"][0]["results"].as_array().unwrap();
221-
assert_eq!(results.len(), 3);
222-
assert_eq!(
223-
results
224-
.iter()
225-
.map(|r| r["message"]["text"].as_str().unwrap())
226-
.collect::<Vec<_>>(),
227-
vec![
228-
"`os` imported but unused",
229-
"Local variable `x` is assigned to but never used",
230-
"Undefined name `a`",
231-
]
232-
);
233-
assert_eq!(rules.len(), 3);
234-
assert_eq!(
235-
rules
236-
.iter()
237-
.map(|r| r["id"].as_str().unwrap())
238-
.collect::<Vec<_>>(),
239-
vec!["F401", "F821", "F841"],
240-
);
215+
let value = serde_json::from_str::<serde_json::Value>(&content).unwrap();
216+
217+
insta::assert_json_snapshot!(value, {
218+
".runs[0].tool.driver.version" => "[VERSION]",
219+
".runs[0].results[].locations[].physicalLocation.artifactLocation.uri" => "[URI]",
220+
});
241221
}
242222
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
---
2+
source: crates/ruff_linter/src/message/sarif.rs
3+
expression: value
4+
---
5+
{
6+
"$schema": "https://json.schemastore.org/sarif-2.1.0.json",
7+
"runs": [
8+
{
9+
"results": [
10+
{
11+
"level": "error",
12+
"locations": [
13+
{
14+
"physicalLocation": {
15+
"artifactLocation": {
16+
"uri": "[URI]"
17+
},
18+
"region": {
19+
"endColumn": 10,
20+
"endLine": 1,
21+
"startColumn": 8,
22+
"startLine": 1
23+
}
24+
}
25+
}
26+
],
27+
"message": {
28+
"text": "`os` imported but unused"
29+
},
30+
"ruleId": "F401"
31+
},
32+
{
33+
"level": "error",
34+
"locations": [
35+
{
36+
"physicalLocation": {
37+
"artifactLocation": {
38+
"uri": "[URI]"
39+
},
40+
"region": {
41+
"endColumn": 6,
42+
"endLine": 6,
43+
"startColumn": 5,
44+
"startLine": 6
45+
}
46+
}
47+
}
48+
],
49+
"message": {
50+
"text": "Local variable `x` is assigned to but never used"
51+
},
52+
"ruleId": "F841"
53+
},
54+
{
55+
"level": "error",
56+
"locations": [
57+
{
58+
"physicalLocation": {
59+
"artifactLocation": {
60+
"uri": "[URI]"
61+
},
62+
"region": {
63+
"endColumn": 5,
64+
"endLine": 1,
65+
"startColumn": 4,
66+
"startLine": 1
67+
}
68+
}
69+
}
70+
],
71+
"message": {
72+
"text": "Undefined name `a`"
73+
},
74+
"ruleId": "F821"
75+
}
76+
],
77+
"tool": {
78+
"driver": {
79+
"informationUri": "https://github.com/astral-sh/ruff",
80+
"name": "ruff",
81+
"rules": [
82+
{
83+
"fullDescription": {
84+
"text": "## What it does\nChecks for unused imports.\n\n## Why is this bad?\nUnused imports add a performance overhead at runtime, and risk creating\nimport cycles. They also increase the cognitive load of reading the code.\n\nIf an import statement is used to check for the availability or existence\nof a module, consider using `importlib.util.find_spec` instead.\n\nIf an import statement is used to re-export a symbol as part of a module's\npublic interface, consider using a \"redundant\" import alias, which\ninstructs Ruff (and other tools) to respect the re-export, and avoid\nmarking it as unused, as in:\n\n```python\nfrom module import member as member\n```\n\nAlternatively, you can use `__all__` to declare a symbol as part of the module's\ninterface, as in:\n\n```python\n# __init__.py\nimport some_module\n\n__all__ = [\"some_module\"]\n```\n\n## Fix safety\n\nFixes to remove unused imports are safe, except in `__init__.py` files.\n\nApplying fixes to `__init__.py` files is currently in preview. The fix offered depends on the\ntype of the unused import. Ruff will suggest a safe fix to export first-party imports with\neither a redundant alias or, if already present in the file, an `__all__` entry. If multiple\n`__all__` declarations are present, Ruff will not offer a fix. Ruff will suggest an unsafe fix\nto remove third-party and standard library imports -- the fix is unsafe because the module's\ninterface changes.\n\n## Example\n\n```python\nimport numpy as np # unused import\n\n\ndef area(radius):\n return 3.14 * radius**2\n```\n\nUse instead:\n\n```python\ndef area(radius):\n return 3.14 * radius**2\n```\n\nTo check the availability of a module, use `importlib.util.find_spec`:\n\n```python\nfrom importlib.util import find_spec\n\nif find_spec(\"numpy\") is not None:\n print(\"numpy is installed\")\nelse:\n print(\"numpy is not installed\")\n```\n\n## Options\n- `lint.ignore-init-module-imports`\n\n## References\n- [Python documentation: `import`](https://docs.python.org/3/reference/simple_stmts.html#the-import-statement)\n- [Python documentation: `importlib.util.find_spec`](https://docs.python.org/3/library/importlib.html#importlib.util.find_spec)\n- [Typing documentation: interface conventions](https://typing.readthedocs.io/en/latest/source/libraries.html#library-interface-public-and-private-symbols)\n"
85+
},
86+
"help": {
87+
"text": "`{name}` imported but unused; consider using `importlib.util.find_spec` to test for availability"
88+
},
89+
"helpUri": "https://docs.astral.sh/ruff/rules/unused-import",
90+
"id": "F401",
91+
"properties": {
92+
"id": "F401",
93+
"kind": "Pyflakes",
94+
"name": "unused-import",
95+
"problem.severity": "error"
96+
},
97+
"shortDescription": {
98+
"text": "`{name}` imported but unused; consider using `importlib.util.find_spec` to test for availability"
99+
}
100+
},
101+
{
102+
"fullDescription": {
103+
"text": "## What it does\nChecks for uses of undefined names.\n\n## Why is this bad?\nAn undefined name is likely to raise `NameError` at runtime.\n\n## Example\n```python\ndef double():\n return n * 2 # raises `NameError` if `n` is undefined when `double` is called\n```\n\nUse instead:\n```python\ndef double(n):\n return n * 2\n```\n\n## Options\n- [`target-version`]: Can be used to configure which symbols Ruff will understand\n as being available in the `builtins` namespace.\n\n## References\n- [Python documentation: Naming and binding](https://docs.python.org/3/reference/executionmodel.html#naming-and-binding)\n"
104+
},
105+
"help": {
106+
"text": "Undefined name `{name}`. {tip}"
107+
},
108+
"helpUri": "https://docs.astral.sh/ruff/rules/undefined-name",
109+
"id": "F821",
110+
"properties": {
111+
"id": "F821",
112+
"kind": "Pyflakes",
113+
"name": "undefined-name",
114+
"problem.severity": "error"
115+
},
116+
"shortDescription": {
117+
"text": "Undefined name `{name}`. {tip}"
118+
}
119+
},
120+
{
121+
"fullDescription": {
122+
"text": "## What it does\nChecks for the presence of unused variables in function scopes.\n\n## Why is this bad?\nA variable that is defined but not used is likely a mistake, and should\nbe removed to avoid confusion.\n\nIf a variable is intentionally defined-but-not-used, it should be\nprefixed with an underscore, or some other value that adheres to the\n[`lint.dummy-variable-rgx`] pattern.\n\nUnder [preview mode](https://docs.astral.sh/ruff/preview), this rule also\ntriggers on unused unpacked assignments (for example, `x, y = foo()`).\n\n## Example\n```python\ndef foo():\n x = 1\n y = 2\n return x\n```\n\nUse instead:\n```python\ndef foo():\n x = 1\n return x\n```\n\n## Options\n- `lint.dummy-variable-rgx`\n"
123+
},
124+
"help": {
125+
"text": "Local variable `{name}` is assigned to but never used"
126+
},
127+
"helpUri": "https://docs.astral.sh/ruff/rules/unused-variable",
128+
"id": "F841",
129+
"properties": {
130+
"id": "F841",
131+
"kind": "Pyflakes",
132+
"name": "unused-variable",
133+
"problem.severity": "error"
134+
},
135+
"shortDescription": {
136+
"text": "Local variable `{name}` is assigned to but never used"
137+
}
138+
}
139+
],
140+
"version": "[VERSION]"
141+
}
142+
}
143+
}
144+
],
145+
"version": "2.1.0"
146+
}

0 commit comments

Comments
 (0)