mews.page/tests/test_coverage.py
randogoth 060d4e00fd refactor: split the repo into self-contained validator, directory, quickstart, spec and site folders
validator/ holds mewslint (lint, css, fetch, DTD/CSS data); directory/ holds
the mews.page service (app, db, check, pages, cli) and depends on validator/;
quickstart/ holds mews-quickstart and md2mews.py for third parties who want
to create Mews content without cloning the repo; spec/ consolidates doc/ and
dtd/ with the canonical mews-0.1.css; site/ becomes a Pelican project with
the forward-facing pages as Markdown, the check form kept as a raw HTML
snippet. Root pyproject.toml is now a virtual uv workspace over validator,
directory and quickstart, with cross-cutting tests that span more than one
of them staying at the repo root. Makefile and flake.nix updated to match.
2026-10-13 12:29:23 +03:00

50 lines
1.5 KiB
Python

"""The validator against the spec it implements.
These are the tests that notice when the spec moves and the validator doesn't.
"""
from pathlib import Path
import re
from mews.lint import CHECKS, NOT_CHECKED
SPEC = Path(__file__).resolve().parent.parent / "spec" / "SPEC.md"
KEYWORD = re.compile(r"\b(MUST NOT|MUST|SHOULD NOT|SHOULD)\b")
HEADING = re.compile(r"^#{2,3} (\d+(?:\.\d+)?)[. ]")
def sections_with_rules() -> set[str]:
"""Every section of SPEC.md 3 to 7 that states a MUST or a SHOULD."""
found: set[str] = set()
current = ""
for line in SPEC.read_text().splitlines():
heading = HEADING.match(line)
if heading:
current = heading.group(1)
continue
if current[:1] in "34567" and KEYWORD.search(line):
found.add(current)
return found
def test_every_rule_in_the_spec_is_checked_or_listed_as_unchecked():
covered = {check.section for check in CHECKS} | set(NOT_CHECKED)
missing = sections_with_rules() - covered
assert not missing, (
f"sections {sorted(missing)} of SPEC.md state rules that mews.lint "
"neither checks nor lists in NOT_CHECKED"
)
def test_the_unchecked_list_says_why():
for section, reason in NOT_CHECKED.items():
assert len(reason) > 20, section
def test_check_codes_are_unique():
codes = [check.code for check in CHECKS]
assert len(codes) == len(set(codes))
def test_every_check_is_a_must_or_a_should():
assert {check.level for check in CHECKS} == {"must", "should"}