Coverage for pytest_beehave/config.py: 100%
45 statements
« prev ^ index » next coverage.py v7.8.0, created at 2026-04-21 04:49 +0000
« prev ^ index » next coverage.py v7.8.0, created at 2026-04-21 04:49 +0000
1"""Configuration reader for pytest-beehave."""
3import tomllib
4from pathlib import Path
5from typing import Literal, cast
7DEFAULT_FEATURES_PATH: str = "docs/features"
8type StubFormat = Literal["functions", "classes"]
9VALID_STUB_FORMATS: tuple[str, ...] = ("functions", "classes")
10DEFAULT_STUB_FORMAT: StubFormat = "functions"
13def _read_beehave_section(rootdir: Path) -> dict[str, object]:
14 """Read the [tool.beehave] section from pyproject.toml.
16 Args:
17 rootdir: Absolute path to the project root.
19 Returns:
20 The [tool.beehave] dict, or empty dict if absent.
21 """
22 pyproject = rootdir / "pyproject.toml"
23 if not pyproject.exists():
24 return {}
25 with pyproject.open("rb") as f:
26 data = tomllib.load(f)
27 return data.get("tool", {}).get("beehave", {})
30def show_steps_in_terminal(rootdir: Path) -> bool:
31 """Return True if show_steps_in_terminal is enabled (default: True).
33 Args:
34 rootdir: Absolute path to the project root.
36 Returns:
37 True unless explicitly set to false in [tool.beehave].
38 """
39 section = _read_beehave_section(rootdir)
40 return bool(section.get("show_steps_in_terminal", True))
43def show_steps_in_html(rootdir: Path) -> bool:
44 """Return True if show_steps_in_html is enabled (default: True).
46 Args:
47 rootdir: Absolute path to the project root.
49 Returns:
50 True unless explicitly set to false in [tool.beehave].
51 """
52 section = _read_beehave_section(rootdir)
53 return bool(section.get("show_steps_in_html", True))
56def _read_configured_path(pyproject: Path) -> str | None:
57 """Read features_path from [tool.beehave] in pyproject.toml.
59 Args:
60 pyproject: Path to the pyproject.toml file.
62 Returns:
63 The configured features_path string, or None if not set.
64 """
65 with pyproject.open("rb") as f:
66 data = tomllib.load(f)
67 tool_section = data.get("tool", {})
68 beehave_section = tool_section.get("beehave", {})
69 return beehave_section.get("features_path")
72def is_explicitly_configured(rootdir: Path) -> bool:
73 """Return True if features_path is explicitly set in [tool.beehave].
75 Args:
76 rootdir: Absolute path to the project root.
78 Returns:
79 True if [tool.beehave].features_path is present in pyproject.toml.
80 """
81 pyproject = rootdir / "pyproject.toml"
82 if not pyproject.exists():
83 return False
84 return _read_configured_path(pyproject) is not None
87def resolve_features_path(rootdir: Path) -> Path:
88 """Resolve the features directory path from config or fall back to default.
90 Args:
91 rootdir: Absolute path to the project root.
93 Returns:
94 Resolved absolute Path to the features directory.
95 """
96 pyproject = rootdir / "pyproject.toml"
97 if not pyproject.exists():
98 return rootdir / DEFAULT_FEATURES_PATH
99 configured = _read_configured_path(pyproject)
100 if configured is None:
101 return rootdir / DEFAULT_FEATURES_PATH
102 return rootdir / configured
105def read_stub_format(rootdir: Path) -> StubFormat:
106 """Read stub_format from [tool.beehave] in pyproject.toml.
108 Args:
109 rootdir: Absolute path to the project root.
111 Returns:
112 The configured StubFormat, or DEFAULT_STUB_FORMAT if absent.
114 Raises:
115 SystemExit: If stub_format has an invalid value.
116 """
117 section = _read_beehave_section(rootdir)
118 value = section.get("stub_format", DEFAULT_STUB_FORMAT)
119 if value not in VALID_STUB_FORMATS:
120 raise SystemExit(
121 f"[beehave] invalid stub_format: {value!r}"
122 f" — valid values are {VALID_STUB_FORMATS}"
123 )
124 return cast(StubFormat, value)