Files
pgr/tests/test_rust_audits.py
2026-09-24 09:21:39 +02:00

138 lines
4.0 KiB
Python

# file: tests/test_rust_audits.py
# version: 1
"""Targeted contracts for the two optional Rust style audits."""
from __future__ import annotations
import pathlib
import subprocess
import sys
import tempfile
import unittest
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1] / "scripts"))
from audit_rust_blank_lines import audit_file as audit_blanks # noqa: E402
from audit_rust_const_blocks import audit_file as audit_consts # noqa: E402
from _rust_audit_common import selected_files # noqa: E402
class RustAuditTests(unittest.TestCase):
def setUp(self) -> None:
self.temporary = tempfile.TemporaryDirectory()
self.addCleanup(self.temporary.cleanup)
self.root = pathlib.Path(self.temporary.name)
def source(self, text: str) -> pathlib.Path:
path = self.root / "source.rs"
path.write_text(text, encoding="utf-8")
return path
def test_clean_body_and_const_visibility_groups(self) -> None:
path = self.source("""pub const ALPHA: u8 = 1;
pub const BETA: u8 = 2;
pub(crate) const GAMMA: u8 = 3;
const OMEGA: u8 = 4;
fn sample() {
let value = r#"{\n\n}"#;
println!("{value}");
}
""")
self.assertEqual(audit_blanks(path), [])
self.assertEqual(audit_consts(path), [])
def test_blank_body_and_repeated_blank_lines(self) -> None:
path = self.source("""fn sample() {
let value = 1;
println!("{value}");
}
""")
issues = audit_blanks(path)
self.assertTrue(any("consecutive" in issue for issue in issues))
self.assertTrue(any("inside fn body" in issue for issue in issues))
def test_blank_string_and_nested_comment_braces_are_ignored(self) -> None:
path = self.source('''fn sample() {
let data = r#"{
}"#;
/* outer { /* inner } */ outer } */
println!("{data}");
}
''')
self.assertEqual(audit_blanks(path), [])
def test_struct_body_and_tuple_struct(self) -> None:
path = self.source("""struct Payload {
x: u8,
y: u8,
}
struct Pair(u8, u8);
""")
self.assertEqual(len(audit_blanks(path)), 1)
self.assertIn("struct body", audit_blanks(path)[0])
def test_const_order_and_multiline_initializer(self) -> None:
path = self.source("""const BETA: [u8; 2] = [
1,
2,
];
const ALPHA: u8 = 1;
pub const GAMMA: u8 = 3;
""")
issues = audit_consts(path)
self.assertTrue(any("alphabetical" in issue for issue in issues))
self.assertTrue(any("visibility" in issue for issue in issues))
def test_const_spacing(self) -> None:
path = self.source("""pub const ALPHA: u8 = 1;
pub const BETA: u8 = 2;
pub(crate) const GAMMA: u8 = 3;
""")
issues = audit_consts(path)
self.assertEqual(sum("blank line(s)" in issue for issue in issues), 2)
def test_const_function_does_not_join_const_block(self) -> None:
path = self.source("""const ZETA: u8 = 1;
const fn compute() -> u8 {
1
}
const ALPHA: u8 = 2;
""")
self.assertEqual(audit_consts(path), [])
def test_scope_and_missing_path(self) -> None:
self.source("fn sample() {}\n")
selected, errors = selected_files([str(self.root), str(self.root / "absent.rs")])
self.assertEqual(len(selected), 1)
self.assertEqual(len(errors), 1)
def test_cli_status_for_success_violation_and_invalid_selection(self) -> None:
path = self.source("const ALPHA: u8 = 1;\nconst BETA: u8 = 2;\n")
script = pathlib.Path(__file__).resolve().parents[1] / "scripts" / "audit_rust_const_blocks.py"
def run(subject: pathlib.Path) -> subprocess.CompletedProcess[str]:
return subprocess.run([sys.executable, "-B", str(script), str(subject)], capture_output=True, text=True, check=False)
self.assertEqual(run(path).returncode, 0)
path.write_text("const BETA: u8 = 1;\nconst ALPHA: u8 = 2;\n", encoding="utf-8")
self.assertEqual(run(path).returncode, 1)
self.assertEqual(run(self.root / "missing.rs").returncode, 2)
if __name__ == "__main__":
unittest.main()