File: test_cli_doc_coverage.py

package info (click to toggle)
python-datamodel-code-generator 0.45.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 9,052 kB
  • sloc: python: 29,621; makefile: 15
file content (123 lines) | stat: -rw-r--r-- 4,831 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
"""Tests to track CLI documentation coverage.

These tests verify that options intended to be documented have:
1. A cli_doc marker in tests
2. An entry in CLI_OPTION_META

The DOCUMENTED_OPTIONS set defines which options should be documented.
This allows gradual expansion of documentation coverage.
"""

from __future__ import annotations

import json
from pathlib import Path
from typing import Any

import pytest

from datamodel_code_generator.cli_options import (
    CLI_OPTION_META,
    MANUAL_DOCS,
    get_all_canonical_options,
    get_canonical_option,
)

COLLECTION_PATH = Path(__file__).parent / ".cli_doc_collection.json"

# Options that should be documented (gradually expand this set)
# Options in this set MUST have:
#   1. A cli_doc marker in tests
#   2. An entry in CLI_OPTION_META
DOCUMENTED_OPTIONS: frozenset[str] = frozenset({
    "--frozen-dataclasses",
    # Add more as cli_doc markers are added to tests...
})


@pytest.fixture(scope="module")
def collection_data() -> dict[str, Any]:  # pragma: no cover
    """Load the CLI doc collection data."""
    if not COLLECTION_PATH.exists():
        pytest.skip(f"CLI doc collection not found at {COLLECTION_PATH}. Run: pytest --collect-cli-docs -p no:xdist")

    with Path(COLLECTION_PATH).open(encoding="utf-8") as f:
        return json.load(f)


@pytest.fixture(scope="module")
def collected_options(collection_data: dict[str, Any]) -> set[str]:  # pragma: no cover
    """Extract canonical options from collection data."""
    options: set[str] = set()
    for item in collection_data.get("items", []):
        options.update(get_canonical_option(opt) for opt in item["marker_kwargs"].get("options", []))
    return options


class TestCLIDocCoverage:  # pragma: no cover
    """Documentation coverage tests."""

    def test_documented_options_have_cli_doc_markers(  # noqa: PLR6301
        self, collected_options: set[str]
    ) -> None:
        """Verify that DOCUMENTED_OPTIONS have cli_doc markers in tests."""
        missing = DOCUMENTED_OPTIONS - collected_options
        if missing:
            pytest.fail(
                "Options in DOCUMENTED_OPTIONS but missing cli_doc marker:\n"
                + "\n".join(f"  - {opt}" for opt in sorted(missing))
                + "\n\nAdd @pytest.mark.cli_doc(...) to tests for these options."
            )

    def test_documented_options_have_meta(self) -> None:  # noqa: PLR6301
        """Verify that DOCUMENTED_OPTIONS have CLI_OPTION_META entries."""
        missing = DOCUMENTED_OPTIONS - set(CLI_OPTION_META.keys())
        if missing:
            pytest.fail(
                "Options in DOCUMENTED_OPTIONS but missing CLI_OPTION_META:\n"
                + "\n".join(f"  - {opt}" for opt in sorted(missing))
                + "\n\nAdd entries to CLI_OPTION_META in cli_options.py."
            )

    def test_documented_options_not_manual(self) -> None:  # noqa: PLR6301
        """Verify that DOCUMENTED_OPTIONS are not in MANUAL_DOCS."""
        overlap = DOCUMENTED_OPTIONS & MANUAL_DOCS
        if overlap:
            pytest.fail(
                "Options in both DOCUMENTED_OPTIONS and MANUAL_DOCS:\n"
                + "\n".join(f"  - {opt}" for opt in sorted(overlap))
            )

    def test_collection_schema_version(  # noqa: PLR6301
        self, collection_data: dict[str, Any]
    ) -> None:
        """Verify that collection data has expected schema version."""
        version = collection_data.get("schema_version")
        assert version is not None, "Collection data missing 'schema_version'"
        assert version == 1, f"Unexpected schema version: {version}"


class TestCoverageStats:  # pragma: no cover
    """Informational tests for coverage statistics."""

    @pytest.mark.skip(reason="Informational: run with -v --no-skip to see stats")
    def test_show_coverage_stats(self, collected_options: set[str]) -> None:  # noqa: PLR6301
        """Display documentation coverage statistics."""
        all_options = get_all_canonical_options()
        documentable = all_options - MANUAL_DOCS
        undocumented = documentable - collected_options

        print(f"\nUndocumented options ({len(undocumented)}):")  # noqa: T201
        for opt in sorted(undocumented):
            print(f"  {opt}")  # noqa: T201

    @pytest.mark.skip(reason="Informational: run with -v --no-skip to see stats")
    def test_show_documented_options(  # noqa: PLR6301
        self, collected_options: set[str]
    ) -> None:
        """Display currently documented options."""
        print(f"\nDocumented options ({len(collected_options)}):")  # noqa: T201
        for opt in sorted(collected_options):
            meta = CLI_OPTION_META.get(opt)
            category = meta.category.value if meta else "General Options"
            print(f"  {opt} ({category})")  # noqa: T201