Coverage for tests / integration / test_built_package.py: 97%
35 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
1"""Integration test for built package installation.
3This module tests that lintro can be installed as a built wheel distribution
4and imported successfully, catching circular import issues that only manifest
5when the package is installed (not in editable mode).
6"""
8from __future__ import annotations
10import subprocess
11import sys
12import tempfile
13from pathlib import Path
15import pytest
16from assertpy import assert_that
19@pytest.mark.slow
20def test_built_wheel_imports() -> None:
21 """Test that lintro can be built and imported as a wheel.
23 This test:
24 1. Builds lintro as a wheel
25 2. Installs it in a fresh virtual environment
26 3. Attempts to import critical modules
27 4. Verifies no circular import errors occur
29 This catches issues that only manifest when lintro is installed as a
30 dependency (built distribution) rather than in editable mode.
31 """
32 project_root = Path(__file__).parent.parent.parent
34 with tempfile.TemporaryDirectory() as tmpdir:
35 tmpdir_path = Path(tmpdir)
36 venv_path = tmpdir_path / "test_venv"
37 dist_dir = tmpdir_path / "dist"
39 # Step 1: Build the wheel
40 build_result = subprocess.run(
41 ["uv", "build", "--out-dir", str(dist_dir)],
42 cwd=str(project_root),
43 capture_output=True,
44 text=True,
45 timeout=60,
46 )
47 assert_that(build_result.returncode).is_equal_to(0)
48 assert_that(dist_dir.exists()).is_true()
50 # Find the built wheel
51 wheels = list(dist_dir.glob("*.whl"))
52 assert_that(wheels).is_not_empty()
53 wheel_path = wheels[0]
55 # Step 2: Create a fresh virtual environment
56 venv_result = subprocess.run(
57 [sys.executable, "-m", "venv", str(venv_path)],
58 capture_output=True,
59 text=True,
60 timeout=30,
61 )
62 assert_that(venv_result.returncode).is_equal_to(0)
64 # Determine the Python executable in the venv
65 if sys.platform == "win32":
66 python_exe = venv_path / "Scripts" / "python.exe"
67 else:
68 python_exe = venv_path / "bin" / "python"
70 assert_that(python_exe.exists()).is_true()
72 # Step 3: Install the wheel in the venv
73 install_result = subprocess.run(
74 [str(python_exe), "-m", "pip", "install", str(wheel_path)],
75 capture_output=True,
76 text=True,
77 timeout=60,
78 )
79 assert_that(install_result.returncode).is_equal_to(0)
81 # Step 4: Test importing lintro modules (this is where circular imports fail)
82 test_imports = [
83 "import lintro",
84 "import lintro.parsers",
85 "from lintro.parsers import bandit",
86 "from lintro.parsers.actionlint.actionlint_parser import parse_actionlint_output", # noqa: E501
87 "from lintro.plugins import ToolRegistry; ToolRegistry.get('actionlint')",
88 "from lintro.cli import cli",
89 ]
91 for import_statement in test_imports:
92 import_result = subprocess.run(
93 [str(python_exe), "-c", import_statement],
94 capture_output=True,
95 text=True,
96 timeout=10,
97 )
98 assert_that(import_result.returncode).described_as(
99 f"Import failed: {import_statement}\n"
100 f"stdout: {import_result.stdout}\n"
101 f"stderr: {import_result.stderr}",
102 ).is_equal_to(0)
104 # Step 5: Test that lintro CLI works
105 cli_result = subprocess.run(
106 [str(python_exe), "-m", "lintro", "--version"],
107 capture_output=True,
108 text=True,
109 timeout=10,
110 )
111 assert_that(cli_result.returncode).is_equal_to(0)
112 assert_that(cli_result.stdout).contains("lintro")