Option C Tools
Loading...
Searching...
No Matches
test_integration.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# tests/tests_linter/test_integration.py
4
5"""
6Purpose
7-------
8Perform end-to-end integration tests of the OCT linter.
9
10Responsibilities
11----------------
12- Run the linter via its Python API.
13- Validate log file creation.
14- Validate summary output.
15- Validate behavior in --fix-headers mode.
16- Validate machine-readable JSON output (--json mode).
17
18Diagnostics
19-----------
20Domain: LINTER-TESTS
21Levels:
22 L2 — lifecycle
23 L3 — semantic details
24 L4 — deep tracing
25
26Contracts
27---------
28- Must simulate a full Option C project.
29- Must not depend on the developer's real environment.
30- Must ensure deterministic behavior across runs.
31"""
32
33import io
34import json
35import sys
36from pathlib import Path
37import oct.linter.oct_lint as oct_lint
38
39
40def test_linter_runs_and_creates_log(temp_project_root: Path):
41 """
42 Run the linter normally and ensure a log file is created.
43 """
44 oct_lint.run_linter(temp_project_root, argv=[])
45
46 logs = list((temp_project_root / "logs").glob("oct_lint_output-*.txt"))
47 assert logs, "Expected at least one log file to be created"
48
49
50def test_linter_fix_headers_mode(temp_project_root: Path, linter_ctx: oct_lint.LinterContext):
51 """
52 Run the linter in --fix-headers mode and ensure the fix is applied.
53 """
54 oct_lint.run_linter(temp_project_root, argv=["--fix-headers"])
55
56 # Validate that minimal_valid.py still passes after fix mode
57 fixture = temp_project_root / "tests_linter" / "fixtures" / "minimal_valid.py"
58 text = fixture.read_text(encoding="utf-8")
59 lines = text.splitlines()
60
61 ok, errors = oct_lint.validate_header_block(lines, fixture, linter_ctx)
62 assert ok, f"Header block should validate after fix mode, errors: {errors}"
63
64
65def test_linter_json_output(temp_project_root: Path):
66 """
67 Run the linter in --json mode and verify the output is valid JSON with
68 the expected top-level structure.
69 """
70 captured = io.StringIO()
71 original_stdout = sys.stdout
72 sys.stdout = captured
73 try:
74 oct_lint.run_linter(temp_project_root, argv=["--json"])
75 finally:
76 sys.stdout = original_stdout
77
78 output = captured.getvalue().strip()
79 assert output, "Expected JSON output on stdout"
80
81 data = json.loads(output)
82
83 assert "project" in data
84 assert "oct_version" in data
85 assert "timestamp" in data
86 assert "summary" in data
87 assert "files" in data
88
89 summary = data["summary"]
90 for key in ("total_files", "fully_compliant", "pass_header", "pass_docstring",
91 "pass_diagnostics_profile", "pass_dbg", "pass_func", "pass_tests"):
92 assert key in summary
93
94 assert isinstance(data["files"], list)
95 for file_entry in data["files"]:
96 assert "path" in file_entry
97 assert "checks" in file_entry
98 assert "compliant" in file_entry
99 for key in ("header", "docstring", "diagnostics_profile", "dbg_usage", "func_pattern", "tests_exist"):
100 assert key in file_entry["checks"]
101 assert "pass" in file_entry["checks"][key]
102 assert "message" in file_entry["checks"][key]
test_linter_fix_headers_mode(Path temp_project_root, oct_lint.LinterContext linter_ctx)
test_linter_runs_and_creates_log(Path temp_project_root)
test_linter_json_output(Path temp_project_root)