diff --git a/src/crapper/runners.py b/src/crapper/runners.py index 84869ee..9b02fbc 100644 --- a/src/crapper/runners.py +++ b/src/crapper/runners.py @@ -361,10 +361,18 @@ def python_sources(package: Path, files: list[Path]) -> str: relative = path.resolve().relative_to(package) except ValueError: continue - tops.add(relative.parts[0]) + tops.add(_source_name(relative)) return ",".join(sorted(tops)) +def _source_name(relative: Path) -> str: + """A top-level module is named without .py, which coverage.py --source requires.""" + + if len(relative.parts) == 1: + return relative.stem + return relative.parts[0] + + def python_coverage_commands( py: str, kind: str, data_file: Path, report: Path, source: str ) -> tuple[list[str], list[str]]: diff --git a/tests/test_runners.py b/tests/test_runners.py index 8a9f554..679e1ba 100644 --- a/tests/test_runners.py +++ b/tests/test_runners.py @@ -542,3 +542,8 @@ def test_vitest_install_restores_manifests_when_install_changes_them(tmp_path, m monkeypatch.setattr("crapper.runners.run_shell", shell) assert _ensure_vitest_coverage(tmp_path) is False assert package_json.read_bytes() == b'{"name":"demo"}\n' + + +def test_python_sources_name_a_top_level_module_without_its_suffix(tmp_path): + module = tmp_path / "carddav.py" + assert python_sources(tmp_path, [module, tmp_path / "test_carddav.py"]) == "carddav"