Skip to content

Commit 4be07b4

Browse files
committed
Add tests for lint:security, lint:typing, lint:code
1 parent 5c5afc5 commit 4be07b4

File tree

2 files changed

+104
-2
lines changed

2 files changed

+104
-2
lines changed

exasol/toolbox/nox/_lint.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@
1616

1717

1818
def _pylint(session: Session, files: Iterable[str]) -> None:
19+
json_file = PROJECT_CONFIG.root / ".lint.json"
20+
txt_file = PROJECT_CONFIG.root / ".lint.txt"
21+
1922
session.run(
2023
"pylint",
2124
"--output-format",
22-
"colorized,json:.lint.json,text:.lint.txt",
25+
f"colorized,json:{json_file},text:{txt_file}",
2326
*files,
2427
)
2528

@@ -47,7 +50,7 @@ def _security_lint(session: Session, files: Iterable[str]) -> None:
4750
"--format",
4851
"json",
4952
"--output",
50-
".security.json",
53+
PROJECT_CONFIG.root / ".security.json",
5154
"--exit-zero",
5255
*files,
5356
)

test/unit/nox/_lint_test.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import json
2+
from inspect import cleandoc
3+
from pathlib import Path
4+
from unittest.mock import patch
5+
6+
import pytest
7+
from nox.command import CommandFailed
8+
9+
from exasol.toolbox.nox._lint import (
10+
lint,
11+
security_lint,
12+
type_check,
13+
)
14+
15+
16+
@pytest.fixture
17+
def file_with_multiple_problems(tmp_path):
18+
"""
19+
In this file with multiple problems, it is expected that the nox
20+
lint sessions would detect the following errors:
21+
22+
* lint:code
23+
* C0304: Final newline missing (missing-final-newline)
24+
* C0114: Missing module docstring (missing-module-docstring)
25+
* W1510: 'subprocess.run' used without explicitly defining the value for 'check'. (subprocess-run-check)
26+
* lint:typing
27+
* Incompatible types in assignment (expression has type "int", variable has type "str") [assignment]
28+
* lint:security
29+
* [B404:blacklist] Consider possible security implications associated with the subprocess module.
30+
* [B607:start_process_with_partial_path] Starting a process with a partial executable path
31+
* [B603:subprocess_without_shell_equals_true] subprocess call - check for execution of untrusted input.
32+
"""
33+
34+
file_path = tmp_path / "dummy_file.py"
35+
text = """
36+
import subprocess
37+
38+
x: str = 2
39+
subprocess.run("ls")
40+
"""
41+
file_path.write_text(cleandoc(text))
42+
return file_path
43+
44+
45+
def test_lint(nox_session, tmp_path, file_with_multiple_problems):
46+
with patch("exasol.toolbox.nox._lint.PROJECT_CONFIG") as config:
47+
config.root = tmp_path
48+
config.source = Path("")
49+
with pytest.raises(CommandFailed, match="Returned code 20"):
50+
lint(session=nox_session)
51+
52+
json_file = tmp_path / ".lint.json"
53+
txt_file = tmp_path / ".lint.txt"
54+
55+
assert json_file.exists()
56+
assert txt_file.exists()
57+
58+
contents = json_file.read_text()
59+
errors = sorted([row["message-id"] for row in json.loads(contents)])
60+
assert errors == ["C0114", "C0304", "W1510"]
61+
62+
63+
def test_type_check(nox_session, tmp_path, file_with_multiple_problems, caplog):
64+
with patch("exasol.toolbox.nox._lint.PROJECT_CONFIG") as config:
65+
config.root = tmp_path
66+
config.source = Path("")
67+
with pytest.raises(CommandFailed, match="Returned code 1"):
68+
type_check(session=nox_session)
69+
70+
assert caplog.messages[1] == (
71+
"Command mypy --explicit-package-bases --namespace-packages --show-error-codes "
72+
"--pretty --show-column-numbers --show-error-context --scripts-are-modules "
73+
f"{file_with_multiple_problems} failed with exit code 1"
74+
)
75+
76+
77+
def test_security_lint(nox_session, tmp_path, file_with_multiple_problems):
78+
with patch("exasol.toolbox.nox._lint.PROJECT_CONFIG") as config:
79+
config.root = tmp_path
80+
config.source = Path("")
81+
security_lint(session=nox_session)
82+
83+
output_file = tmp_path / ".security.json"
84+
assert output_file.exists()
85+
86+
contents = output_file.read_text()
87+
assert json.loads(contents)["metrics"]["_totals"] == {
88+
"CONFIDENCE.HIGH": 3,
89+
"CONFIDENCE.LOW": 0,
90+
"CONFIDENCE.MEDIUM": 0,
91+
"CONFIDENCE.UNDEFINED": 0,
92+
"SEVERITY.HIGH": 0,
93+
"SEVERITY.LOW": 3,
94+
"SEVERITY.MEDIUM": 0,
95+
"SEVERITY.UNDEFINED": 0,
96+
"loc": 3,
97+
"nosec": 0,
98+
"skipped_tests": 0,
99+
}

0 commit comments

Comments
 (0)