diff --git a/CHANGELOG.md b/CHANGELOG.md index 242ce1f..e6f4ea4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Hits count for test coverage. [#91] +### Fixed +- Few edge cases with zero entities. [#92] + ## [0.3.10] - 2025-10-12 ### Added - Support for `dbt==1.9`. [#85] diff --git a/dbt_coverage/__init__.py b/dbt_coverage/__init__.py index e7a5893..fcfc2f6 100644 --- a/dbt_coverage/__init__.py +++ b/dbt_coverage/__init__.py @@ -323,16 +323,12 @@ class ColumnRef: covered: Set[ColumnRef] total: Set[ColumnRef] misses: Set[ColumnRef] = field(init=False) - coverage: float = field(init=False) + coverage: Optional[float] = field(init=False) subentities: Dict[str, CoverageReport] def __post_init__(self): - if self.covered is not None and self.total is not None and len(self.total) != 0: - self.misses = self.total - self.covered - self.coverage = len(self.covered) / len(self.total) - else: - self.misses = None - self.coverage = None + self.misses = self.total - self.covered + self.coverage = len(self.covered) / len(self.total) if self.total else None @classmethod def from_catalog(cls, catalog: Catalog, cov_type: CoverageType): @@ -584,9 +580,12 @@ def summary(self): buf.write(f"{'':10}{'before':>10}{'after':>10}{'+/-':>15}\n") buf.write("=" * 45 + "\n") + + before_cov = self.before.coverage if self.before.coverage is not None else 0.0 + after_cov = self.after.coverage if self.after.coverage is not None else 0.0 buf.write( - f"{'Coverage':10}{self.before.coverage:10.2%}{self.after.coverage:10.2%}" - f"{(self.after.coverage - self.before.coverage):+15.2%}\n" + f"{'Coverage':10}{before_cov:10.2%}{after_cov:10.2%}" + f"{(after_cov - before_cov):+15.2%}\n" ) buf.write("=" * 45 + "\n") @@ -684,10 +683,16 @@ def _new_miss_summary_row(self): before_covered = len(self.before.covered) if self.before is not None else "-" before_total = len(self.before.total) if self.before is not None else "-" - before_coverage = f"({self.before.coverage:.2%})" if self.before is not None else "(-)" + before_coverage = ( + f"({self.before.coverage:.2%})" + if self.before is not None and self.before.coverage is not None + else "(-)" + ) after_covered = len(self.after.covered) after_total = len(self.after.total) - after_coverage = f"({self.after.coverage:.2%})" + after_coverage = ( + f"({self.after.coverage:.2%})" if self.after.coverage is not None else "(-)" + ) buf = io.StringIO() buf.write(f"{title:50}") diff --git a/tests/unit/test_init.py b/tests/unit/test_init.py index 9590f8a..e4d9d00 100644 --- a/tests/unit/test_init.py +++ b/tests/unit/test_init.py @@ -1,6 +1,6 @@ import pytest -from dbt_coverage import Catalog, CoverageReport, CoverageType +from dbt_coverage import Catalog, CoverageDiff, CoverageReport, CoverageType @pytest.mark.parametrize("cov_type", [CoverageType.DOC, CoverageType.TEST]) @@ -15,5 +15,16 @@ def test_coverage_report_with_zero_tables(cov_type): assert coverage_report.hits == 0 assert len(coverage_report.total) == 0 assert coverage_report.coverage is None - assert coverage_report.misses is None + assert len(coverage_report.misses) == 0 assert coverage_report.subentities == {} + + +@pytest.mark.parametrize("cov_type", [CoverageType.DOC, CoverageType.TEST]) +def test_coverage_diff_with_zero_tables(cov_type): + empty_catalog = Catalog(tables={}) + coverage_report_1 = CoverageReport.from_catalog(empty_catalog, cov_type) + coverage_report_2 = CoverageReport.from_catalog(empty_catalog, cov_type) + + diff = CoverageDiff(coverage_report_1, coverage_report_2) + + assert len(diff.new_misses) == 0