Option C Tools
Loading...
Searching...
No Matches
conftest.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# tests/tests_linter/conftest.py
4
5
6"""
7Purpose
8-------
9Provide pytest fixtures for the OCT linter test suite.
10
11Responsibilities
12----------------
13- Create a temporary, isolated Option C project root.
14- Populate the required Option C project structure.
15- Copy fixture files into the temporary project.
16- Provide a ``LinterContext`` fixture for unit tests that call linter
17 functions directly, without triggering ``run_linter()``.
18- Ensure each test runs in a clean, deterministic environment.
19
20Diagnostics
21-----------
22Domain: LINTER-TESTS
23Levels:
24 L2 — lifecycle
25 L3 — semantic details
26 L4 — deep tracing
27
28Contracts
29---------
30- Must not import or modify the developer's real project.
31- Must not modify fixture files.
32- Must ensure deterministic test environments.
33"""
34
35from pathlib import Path
36import shutil
37import pytest
38from oct.linter import oct_lint
39
40
41@pytest.fixture
42def temp_project_root(tmp_path: Path) -> Path:
43 """
44 Create a temporary Option C project root with:
45 - docs/
46 - tests/
47 - oc_diagnostics/
48 - logs/
49 - tests_linter/fixtures copied in
50 """
51 root = tmp_path / "test-project"
52 root.mkdir()
53
54 # Required Option C directories
55 (root / "docs").mkdir()
56 (root / "tests").mkdir()
57 (root / "oc_diagnostics").mkdir()
58 (root / "logs").mkdir()
59 (root / "tests_linter").mkdir()
60 (root / "tests_linter" / "fixtures").mkdir(parents=True)
61
62 # Required Option C project-level files
63 (root / "docs" / "ARCHITECTURE.md").write_text("# Architecture\n", encoding="utf-8")
64 (root / "tests" / "run_tests.py").write_text("print('tests')\n", encoding="utf-8")
65 (root / "tests" / "Tests_README.md").write_text("Tests\n", encoding="utf-8")
66 (root / "oc_diagnostics" / "debug_config.json").write_text(
67 '{\n'
68 ' "domains": {\n'
69 ' "GENERAL": {\n'
70 ' "level": 2,\n'
71 ' "color": "default"\n'
72 ' }\n'
73 ' },\n'
74 ' "global_settings": {\n'
75 ' "silent_mode": false,\n'
76 ' "enable_timestamps": true,\n'
77 ' "enable_colors": true,\n'
78 ' "include_filename": true,\n'
79 ' "output_mode": "both",\n'
80 ' "instrumentation_enabled": false,\n'
81 ' "max_log_files": 10,\n'
82 ' "max_log_size_mb": 5.0,\n'
83 ' "instrumentation_allow_all": false,\n'
84 ' "mode": "dev",\n'
85 ' "http_redact_headers": [\n'
86 ' "authorization",\n'
87 ' "cookie",\n'
88 ' "set-cookie",\n'
89 ' "x-api-key"\n'
90 ' ]\n'
91 ' }\n'
92 '}\n',
93 encoding="utf-8"
94 )
95
96 # Copy fixtures from the real project
97 project_root = Path.cwd()
98 fixtures_src = project_root / "tests" / "tests_linter" / "fixtures"
99 fixtures_dst = root / "tests_linter" / "fixtures"
100
101 for f in fixtures_src.glob("*.py"):
102 dst = fixtures_dst / f.name
103 shutil.copy2(f, dst)
104 # Rewrite line 3 (file-identity comment) to match the temp project path
105 rel = dst.relative_to(root).as_posix()
106 lines = dst.read_text(encoding="utf-8").splitlines(True)
107 if len(lines) >= 3 and lines[2].startswith("# "):
108 lines[2] = f"# {rel}\n"
109 dst.write_text("".join(lines), encoding="utf-8")
110
111 yield root
112
113
114@pytest.fixture
115def linter_ctx(temp_project_root: Path) -> oct_lint.LinterContext:
116 """
117 Return a ``LinterContext`` for the temporary project root.
118
119 Use this fixture in unit tests that call linter check functions
120 (``validate_header_block``, ``fix_header_block``, ``check_tests_exist``)
121 directly, rather than going through ``run_linter()``.
122 """
123 root = temp_project_root
124 _oc_diag = root / "oc_diagnostics"
126 project_root=root,
127 project_name=root.name,
128 diagnostics_dir=_oc_diag if _oc_diag.exists() else root / "diagnostics",
129 tests_dir=root / "tests",
130 docs_dir=root / "docs",
131 )
oct_lint.LinterContext linter_ctx(Path temp_project_root)
Definition conftest.py:115
Path temp_project_root(Path tmp_path)
Definition conftest.py:42