Files
ai-exchange/tests/unit/test_documentation_consistency.py
T

4524 lines
202 KiB
Python

import ast
import re
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
PROJECT_README = ROOT / "README.md"
TRAINING_PRODUCT_DOC = ROOT / "docs" / "training_case_engine_m1_m6_product_readme.md"
TRAINING_PACKAGE_SMOKE_DOC = ROOT / "docs" / "examples" / "training_case_package_smoke_m6.md"
TRAINING_DOCS_CLI_TEST = ROOT / "tests" / "unit" / "test_training_case_docs_cli_m10.py"
TRAINING_DASHBOARD_HTML = ROOT / "src" / "web" / "index.html"
TRAINING_DASHBOARD_APP = ROOT / "src" / "web" / "app.js"
API_SERVER = ROOT / "src" / "api" / "server.py"
OFFLINE_CHECKS_SCRIPT = ROOT / "scripts" / "run_offline_checks.py"
CURRENT_TRAINING_DOC_MATURITY_END = 40
CURRENT_TRAINING_DOC_MATURITY_MARKER = f"M1-M{CURRENT_TRAINING_DOC_MATURITY_END}"
CURRENT_TRAINING_DOC_MATURITY_SPAN = f"through M{CURRENT_TRAINING_DOC_MATURITY_END}"
CURRENT_TRAINING_DOC_MATURITY_PHRASE = (
f"current product maturity {CURRENT_TRAINING_DOC_MATURITY_SPAN}"
)
TRAINING_M24_M29_DOCUMENTATION_TEST_INVENTORY = {
"m1_m40_maturity_wording": (
"test_training_case_product_doc_reflects_current_m40_maturity",
),
"route_surface": (
"test_training_case_product_doc_api_routes_match_server_route_request",
"test_training_case_public_route_registry_is_documented_and_supported",
"test_training_case_product_doc_api_surface_wording_matches_public_routes",
"test_training_dashboard_routes_are_documented_public_api_routes",
),
"dashboard_public_docs_privacy": (
"test_training_readmes_name_dashboard_privacy_and_offline_registry_coverage",
"test_training_dashboard_and_public_docs_keep_privacy_wording_exclusionary",
),
"offline_registry_coverage": (
"test_training_readmes_name_dashboard_privacy_and_offline_registry_coverage",
),
}
TRAINING_M24_M29_PACKAGE_DOCS_INVENTORY_TEST = (
"test_m24_m29_package_docs_privacy_test_inventory_is_current"
)
TRAINING_CASE_ACCEPTANCE_TEST_MANIFEST = (
"test_training_case_engine_m1",
"test_training_api_m2",
"test_training_dashboard_m3",
"test_training_api_m4",
"test_training_case_import_export_m5",
"test_training_public_api_contract_m8",
"test_training_api_error_contract_m9",
"test_training_case_docs_cli_m10",
"test_training_public_export_privacy_m15",
"test_documentation_consistency",
)
TRAINING_CASE_REQUIRED_ACCEPTANCE_TEST_MODULES = (
"test_training_case_engine_m1",
"test_training_api_m2",
"test_training_dashboard_m3",
"test_training_api_m4",
"test_training_case_import_export_m5",
"test_training_public_api_contract_m8",
"test_training_api_error_contract_m9",
"test_training_case_docs_cli_m10",
"test_training_public_export_privacy_m15",
"test_documentation_consistency",
)
TRAINING_PUBLIC_API_ROUTE_REGISTRY = (
("GET", "/training/cases"),
("POST", "/training/cases/import"),
("GET", "/training/cases/export"),
("GET", "/training/cases/{case_id}"),
("POST", "/training/attempts"),
("POST", "/training/attempts/{attempt_id}/annotations"),
("POST", "/training/attempts/{attempt_id}/submit"),
("GET", "/training/progress"),
)
TRAINING_DASHBOARD_ROUTE_REGISTRY = (
("GET", "/training/cases"),
("GET", "/training/progress"),
("POST", "/training/attempts"),
("POST", "/training/attempts/{attempt_id}/annotations"),
("POST", "/training/attempts/{attempt_id}/submit"),
)
TRAINING_ROUTE_SURFACE_WORDING = {
("GET", "/training/cases"): ("list cases", "status", "skill tag", "instrument", "limit filters"),
("POST", "/training/cases/import"): ("import a versioned public package", "cases plus tasks"),
("GET", "/training/cases/export"): ("export a public package", "same case filters"),
("GET", "/training/cases/{case_id}"): ("read one public case",),
("POST", "/training/attempts"): ("start an attempt", "case"),
("POST", "/training/attempts/{attempt_id}/annotations"): ("save an annotation payload", "attempt"),
("POST", "/training/attempts/{attempt_id}/submit"): ("submit an attempt", "optional score"),
("GET", "/training/progress"): ("list progress", "user", "skill tag", "limit filters"),
}
TRAINING_DASHBOARD_PUBLIC_WORDING = (
"available cases",
"user progress",
"attempt start",
"annotation note save",
"attempt submit",
"public case fields only",
)
TRAINING_ACCEPTANCE_VALIDATION_DOC_SNIPPETS = (
"M35 acceptance posture",
"Training Case acceptance manifest",
"focused milestone test suites",
"offline checks",
"public validation",
)
TRAINING_M41_RELEASE_INDEX_DOCS = (PROJECT_README, TRAINING_PRODUCT_DOC)
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY = (
"test_training_readmes_expose_m1_m40_release_index_without_raw_test_modules",
"test_training_m41_release_index_guard_inventory_is_current",
"test_training_m41_release_index_inventory_shape_is_stable",
"test_training_m47_release_index_per_doc_helper_inventory_self_lock_is_current",
"test_training_m48_release_index_per_doc_helper_keeps_doc_tuple_shape",
"test_training_m49_release_index_per_doc_helper_handles_empty_docs_without_mutation",
"test_training_m50_release_index_helper_accepts_flattened_inventory_complete_doc",
"test_training_m54_release_index_required_snippet_inventory_category_shape_is_locked",
"test_training_m55_release_index_required_snippet_inventory_source_shape_is_locked",
"test_training_m56_release_index_required_snippet_inventory_source_shape_rejects_dynamic_fixtures",
"test_training_m57_release_index_required_snippet_inventory_source_shape_diagnostics_are_locked",
"test_training_m58_release_index_required_snippet_inventory_source_shape_accepts_literal_fixtures",
"test_training_m59_release_index_required_snippet_inventory_source_shape_preserves_literal_order",
"test_training_m60_release_index_source_shape_fixture_guard_inventory_self_lock_is_current",
"test_training_m61_release_index_source_shape_fixture_guard_methods_constant_source_shape_is_locked",
"test_training_m62_release_index_source_shape_fixture_guard_methods_reject_dynamic_constant_sources",
"test_training_m63_release_index_source_shape_fixture_guard_methods_constant_diagnostics_are_locked",
"test_training_m64_release_index_source_shape_fixture_guard_methods_accept_valid_literal_sources",
"test_training_m65_release_index_source_shape_fixture_guard_methods_constant_inventory_exactness_self_lock",
"test_training_m66_release_index_source_shape_fixture_guard_methods_constant_source_exactness_self_lock",
"test_training_m67_release_index_source_shape_fixture_guard_methods_constant_inventory_source_exactness_bridge_self_lock",
"test_training_m69_release_index_source_shape_fixture_guard_methods_constant_inventory_source_exactness_bridge_duplicate_negative_fixture_self_lock",
"test_training_m70_release_index_source_shape_fixture_guard_methods_constant_inventory_source_exactness_bridge_duplicate_guard_positive_diagnostic_self_lock",
"test_training_m71_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_source_shape_self_lock",
"test_training_m72_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_rejects_dynamic_sources",
"test_training_m73_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostics_are_locked",
"test_training_m74_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_self_lock",
"test_training_m75_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_self_lock",
"test_training_m76_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_rejects_dynamic_sources",
"test_training_m77_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_edge_diagnostics_are_locked",
"test_training_m78_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_accepts_ordered_literal_sources",
"test_training_m79_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_self_lock",
"test_training_m80_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_negative_fixture_self_lock",
"test_training_m81_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_self_lock",
"test_training_m82_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_rejects_dynamic_sources",
"test_training_m83_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_edge_diagnostics_are_locked",
"test_training_m84_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_inventory_self_lock",
"test_training_m85_release_index_public_docs_acceptance_inventory_alignment_self_lock",
"test_training_m86_release_index_final_closure_delivery_index_self_lock",
"test_training_m87_release_index_final_closure_delivery_index_guard_self_lock",
"test_training_m88_release_index_final_closure_delivery_guard_source_self_lock",
"test_training_m89_release_index_final_closure_delivery_guard_source_chain_self_lock",
"test_training_m90_release_index_final_closure_delivery_guard_source_chain_source_shape_self_lock",
"test_training_m91_release_index_final_closure_delivery_guard_source_chain_source_shape_local_names_self_lock",
"test_training_m92_release_index_final_closure_delivery_guard_source_chain_source_shape_local_names_registration_self_lock",
"test_training_m53_release_index_doc_category_coverage_is_exact",
"test_training_case_product_doc_reflects_current_m40_maturity",
)
TRAINING_M41_RELEASE_INDEX_EXACTNESS_BRIDGE_GUARD_METHODS = (
"test_training_m65_release_index_source_shape_fixture_guard_methods_constant_inventory_exactness_self_lock",
"test_training_m66_release_index_source_shape_fixture_guard_methods_constant_source_exactness_self_lock",
"test_training_m67_release_index_source_shape_fixture_guard_methods_constant_inventory_source_exactness_bridge_self_lock",
)
TRAINING_M41_RELEASE_INDEX_SOURCE_SHAPE_FIXTURE_GUARD_METHODS = (
"test_training_m55_release_index_required_snippet_inventory_source_shape_is_locked",
"test_training_m56_release_index_required_snippet_inventory_source_shape_rejects_dynamic_fixtures",
"test_training_m57_release_index_required_snippet_inventory_source_shape_diagnostics_are_locked",
"test_training_m58_release_index_required_snippet_inventory_source_shape_accepts_literal_fixtures",
"test_training_m59_release_index_required_snippet_inventory_source_shape_preserves_literal_order",
"test_training_m60_release_index_source_shape_fixture_guard_inventory_self_lock_is_current",
"test_training_m61_release_index_source_shape_fixture_guard_methods_constant_source_shape_is_locked",
"test_training_m62_release_index_source_shape_fixture_guard_methods_reject_dynamic_constant_sources",
"test_training_m63_release_index_source_shape_fixture_guard_methods_constant_diagnostics_are_locked",
"test_training_m64_release_index_source_shape_fixture_guard_methods_accept_valid_literal_sources",
)
TRAINING_M41_RELEASE_INDEX_DIAGNOSTIC_FIXTURE_INVENTORY_GUARD_CLUSTER = (
"test_training_m74_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_self_lock",
"test_training_m75_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_self_lock",
"test_training_m76_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_rejects_dynamic_sources",
"test_training_m77_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_edge_diagnostics_are_locked",
"test_training_m78_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_accepts_ordered_literal_sources",
)
TRAINING_M41_RELEASE_INDEX_DIAGNOSTIC_FIXTURE_INVENTORY_GUARD_CLUSTER_GOVERNANCE_METHODS = (
"test_training_m79_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_self_lock",
"test_training_m80_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_negative_fixture_self_lock",
"test_training_m81_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_self_lock",
"test_training_m82_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_rejects_dynamic_sources",
"test_training_m83_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_edge_diagnostics_are_locked",
)
TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY = (
(
"current_m1_m40_marker",
(
"M1-M40",
"through M40",
"current product maturity through M40",
),
),
(
"acceptance_offline_validation",
(
"M35 acceptance posture",
"Training Case acceptance manifest",
"focused milestone test suites",
"offline checks",
"public validation",
),
),
(
"public_api_privacy_contracts",
(
"API contract coverage",
"error contract coverage",
"privacy contract coverage",
),
),
(
"package_smoke_offline_registry",
(
"package smoke",
"training_case_package",
),
),
(
"dashboard_public_docs_privacy",
(
"dashboard_js_syntax",
"dashboard and public docs privacy smoke coverage",
),
),
(
"single_set_docker_deployment",
(
"single-set local Docker deployment",
),
),
(
"docker_smoke_guard_coverage",
(
"Docker smoke guard coverage",
),
),
)
TRAINING_M41_RELEASE_INDEX_DOC_SNIPPETS = tuple(
snippet
for _, snippets in TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY
for snippet in snippets
)
TRAINING_M41_STALE_RELEASE_INVENTORY_NAMES = ("m1_m28_maturity_wording",)
TRAINING_M41_STALE_RELEASE_WORDING = (
"M1-M39",
"through M39",
"through-M39",
)
TRAINING_RAW_TEST_MODULE_PATTERN = r"\btest_training_[a-z0-9_]+"
TRAINING_PUBLIC_PRIVACY_DOCS = (PROJECT_README, TRAINING_PRODUCT_DOC, TRAINING_PACKAGE_SMOKE_DOC)
TRAINING_PUBLIC_ERROR_DOCS = (PROJECT_README, TRAINING_PRODUCT_DOC)
TRAINING_PUBLIC_ERROR_RAW_WORDING_DOCS = (
PROJECT_README,
TRAINING_PRODUCT_DOC,
TRAINING_PACKAGE_SMOKE_DOC,
)
TRAINING_PUBLIC_ERROR_CATALOG_SNIPPETS = (
"Training public error catalog",
"deterministic public validation errors",
"`400` with `invalid_json_body`",
"`400` with `missing_required_json_field:<field>`",
"`400` with `invalid_json_field:<field>`",
"`400` with `invalid_path_param:<field>`",
"`400` with `invalid_limit_query_param:limit`",
"`404` with `not_found`",
"`500` with `internal_server_error`",
"masks raw internals",
"Package CLI public errors",
"one-line JSON",
"`input_file_not_found`",
"`input_path_is_directory`",
"invalid output targets",
)
TRAINING_PUBLIC_ERROR_FORBIDDEN_RAW_WORDING = (
"Traceback",
"stack trace",
"[Errno",
"FileNotFoundError",
"IsADirectoryError",
"OSError",
"No such file or directory",
"Permission denied",
)
TRAINING_PUBLIC_PRIVACY_FORBIDDEN_TERMS = (
"answer" + "_key",
"answer " + "key",
"private " + "answer",
"answer " + "detail",
"solution " + "key",
"solution_" + "key",
)
TRAINING_PUBLIC_PRIVACY_MATERIAL_PHRASES = (
"private solution material",
"internal solution details",
)
LOCAL_DOCKER_POLICY_DOCS = (PROJECT_README, TRAINING_PRODUCT_DOC)
LOCAL_DOCKER_DOCUMENTATION_GUARD_TEST_INVENTORY = (
"test_readmes_describe_single_set_local_docker_deployment_policy",
"test_readmes_lock_single_set_docker_smoke_command_shape",
)
LOCAL_DOCKER_DOCUMENTATION_GUARD_SOURCE_CONSTANTS = (
"LOCAL_DOCKER_POLICY_DOCS",
"LOCAL_DOCKER_REBUILD_COMMANDS",
"LOCAL_DOCKER_SMOKE_COMMANDS",
"LOCAL_DOCKER_COMPOSE_PREFIX",
)
LOCAL_DOCKER_DEPLOY_DIR = "/root/deploy/ai-ict"
LOCAL_DOCKER_COMPOSE_PROJECT = "ai-ict"
LOCAL_DOCKER_CONTAINER = "ai-ict"
LOCAL_DOCKER_COMPOSE_FILE = f"{LOCAL_DOCKER_DEPLOY_DIR}/docker-compose.yml"
LOCAL_DOCKER_COMPOSE_PREFIX = (
f"docker compose -p {LOCAL_DOCKER_COMPOSE_PROJECT} -f {LOCAL_DOCKER_COMPOSE_FILE}"
)
LOCAL_DOCKER_REBUILD_COMMANDS = (
f"{LOCAL_DOCKER_COMPOSE_PREFIX} down --remove-orphans",
f"{LOCAL_DOCKER_COMPOSE_PREFIX} up -d --build",
)
LOCAL_DOCKER_SMOKE_COMMANDS = (
f"{LOCAL_DOCKER_COMPOSE_PREFIX} ps",
"test \"$(docker ps --filter label=com.docker.compose.project=ai-ict --format '{{.Names}}' | wc -l | tr -d ' ')\" = \"1\"",
"test \"$(docker ps --filter name=^/ai-ict$ --format '{{.Names}}' | wc -l | tr -d ' ')\" = \"1\"",
"test \"$(docker inspect -f '{{.State.Health.Status}}' ai-ict)\" = \"healthy\"",
)
LOCAL_DOCKER_POLICY_REQUIRED_SNIPPETS = (
"single-set local Docker deployment",
"compose project `ai-ict`",
"container `ai-ict`",
"deploy directory `/root/deploy/ai-ict`",
"exactly one active deployment set",
"one active `ai-ict` container",
"do not create a second local stack or a second `ai-ict` container",
*LOCAL_DOCKER_REBUILD_COMMANDS,
*LOCAL_DOCKER_SMOKE_COMMANDS,
)
LOCAL_DOCKER_POLICY_FORBIDDEN_ENCOURAGEMENT = (
"create another local stack",
"create a second active deployment set",
"run parallel local stacks",
"keep multiple active deployment sets",
"start an extra ai-ict container",
"duplicate ai-ict containers",
)
TRAINING_PUBLIC_PRIVACY_EXCLUSION_WORDS = (
"scrub",
"omit",
"reject",
"keep",
"out of",
"do not",
"does not",
"without",
"hides",
"not return",
)
TRAINING_DASHBOARD_FETCH_PATTERNS = (
(("GET", "/training/cases"), r"fetchJson\('/training/cases'\)"),
(("GET", "/training/progress"), r"fetchJson\('/training/progress'\)"),
(("POST", "/training/attempts"), r"fetchJson\('/training/attempts',\s*\{\s*method:\s*'POST'"),
(
("POST", "/training/attempts/{attempt_id}/annotations"),
r"fetchJson\(`/training/attempts/\$\{[^}]+\}/annotations`,\s*\{\s*method:\s*'POST'",
),
(
("POST", "/training/attempts/{attempt_id}/submit"),
r"fetchJson\(`/training/attempts/\$\{[^}]+\}/submit`,\s*\{\s*method:\s*'POST'",
),
)
def _training_api_surface_rows_from_product_doc() -> tuple[tuple[str, str, str], ...]:
text = _training_product_doc_section("API Surface")
rows = []
for method, path, capability in re.findall(
r"^\|\s*([A-Z]+)\s*\|\s*`([^`]+)`\s*\|\s*([^|\n]+?)\s*\|",
text,
re.MULTILINE,
):
if path.startswith("/training/"):
rows.append((method, path, " ".join(capability.split()).lower()))
return tuple(rows)
def _training_api_routes_from_product_doc() -> tuple[tuple[str, str], ...]:
return tuple((method, path) for method, path, _capability in _training_api_surface_rows_from_product_doc())
def _supported_training_routes_from_route_request() -> tuple[tuple[str, str], ...]:
source = _route_request_source()
routes = list(
re.findall(
r'if method == "(GET|POST)" and path == "(/training/[^"]+)":',
source,
)
)
for pattern, route in (
(
r'if method == "GET" and len\(path_parts\) == 3 and path_parts\[:2\] == \["training", "cases"\]:\s+case_id = _parse_path_int\(path_parts\[2\], "case_id"\)',
("GET", "/training/cases/{case_id}"),
),
(
r'if method == "POST" and len\(path_parts\) == 4 and path_parts\[:2\] == \["training", "attempts"\] and path_parts\[3\] == "annotations":\s+attempt_id = _parse_path_int\(path_parts\[2\], "attempt_id"\)',
("POST", "/training/attempts/{attempt_id}/annotations"),
),
(
r'if method == "POST" and len\(path_parts\) == 4 and path_parts\[:2\] == \["training", "attempts"\] and path_parts\[3\] == "submit":\s+attempt_id = _parse_path_int\(path_parts\[2\], "attempt_id"\)',
("POST", "/training/attempts/{attempt_id}/submit"),
),
):
if re.search(pattern, source):
routes.append(route)
return tuple(routes)
def _training_dashboard_routes_from_app() -> tuple[tuple[str, str], ...]:
source = TRAINING_DASHBOARD_APP.read_text(encoding="utf-8")
routes = []
for route, pattern in TRAINING_DASHBOARD_FETCH_PATTERNS:
if re.search(pattern, source, re.DOTALL):
routes.append(route)
return tuple(routes)
def _training_dashboard_fetch_paths_from_app() -> tuple[str, ...]:
source = TRAINING_DASHBOARD_APP.read_text(encoding="utf-8")
paths = []
for match in re.finditer(r"fetchJson\(\s*['`](?P<path>/training/[^'`]+)['`]", source):
path = re.sub(r"\$\{[^}]+\}", "{attempt_id}", match.group("path"))
paths.append(path.split("?", 1)[0])
return tuple(paths)
def _route_request_source() -> str:
source = API_SERVER.read_text(encoding="utf-8")
match = re.search(r"^def route_request\(.*?(?=^class APIRequestHandler)", source, re.DOTALL | re.MULTILINE)
if match is None:
raise AssertionError("src/api/server.py is missing route_request")
return match.group(0)
def _training_product_doc_section(heading: str) -> str:
text = TRAINING_PRODUCT_DOC.read_text(encoding="utf-8")
match = re.search(
rf"^## {re.escape(heading)}\n(?P<section>.*?)(?:\n## |\Z)",
text,
re.DOTALL | re.MULTILINE,
)
if match is None:
raise AssertionError(f"Training product README is missing the {heading} section")
return match.group("section")
def _training_validation_section() -> str:
return _training_product_doc_section("Validation And Errors")
def _local_docker_deployment_section(path: Path) -> str:
text = path.read_text(encoding="utf-8")
match = re.search(
r"^## Local Docker [Dd]eployment\n(?P<section>.*?)(?:\n## |\Z)",
text,
re.DOTALL | re.MULTILINE,
)
if match is None:
raise AssertionError(f"{path} is missing the Local Docker deployment section")
return match.group("section")
def _local_docker_command_lines(text: str) -> tuple[str, ...]:
return tuple(
line.strip()
for line in text.splitlines()
if line.strip().startswith(("docker ", "test "))
)
def _training_public_privacy_lines(text: str) -> tuple[str, ...]:
lines = []
for line in text.splitlines():
lower_line = line.lower()
if any(phrase in lower_line for phrase in TRAINING_PUBLIC_PRIVACY_MATERIAL_PHRASES):
lines.append(lower_line.strip())
return tuple(lines)
def _test_method_names_from_file(path: Path, class_name: str) -> tuple[str, ...]:
tree = ast.parse(path.read_text(encoding="utf-8"))
for node in tree.body:
if isinstance(node, ast.ClassDef) and node.name == class_name:
return tuple(
item.name
for item in node.body
if isinstance(item, ast.FunctionDef) and item.name.startswith("test_")
)
raise AssertionError(f"{path} is missing {class_name}")
def _release_index_missing_required_snippets_by_doc(
text_by_doc: dict[Path, str],
) -> dict[Path, tuple[tuple[str, str], ...]]:
return {
path: tuple(
(surface, snippet)
for surface, snippets in TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY
for snippet in snippets
if snippet not in text
)
for path, text in text_by_doc.items()
}
class DocumentationConsistencyTests(unittest.TestCase):
def test_readme_lists_script_output_json_environment_variables(self) -> None:
script_env_vars = set()
for path in (ROOT / "scripts").glob("*.py"):
script_env_vars.update(re.findall(r'"([A-Z0-9_]+OUTPUT_JSON)"', path.read_text(encoding="utf-8")))
readme = (ROOT / "README.md").read_text(encoding="utf-8")
missing = sorted(name for name in script_env_vars if name not in readme)
self.assertEqual(missing, [])
def test_training_case_product_doc_lists_public_m1_m21_surface(self) -> None:
text = TRAINING_PRODUCT_DOC.read_text(encoding="utf-8")
for snippet in (
"Training panel",
"/training/cases",
"/training/cases/{case_id}",
"/training/cases/export",
"/training/cases/import",
"/training/attempts",
"/training/attempts/{attempt_id}/annotations",
"/training/attempts/{attempt_id}/submit",
"/training/progress",
".venv/bin/python scripts/run_training_case_package.py",
".venv/bin/python scripts/run_offline_checks.py",
"private solution material",
"Data Isolation Guarantees",
):
with self.subTest(snippet=snippet):
self.assertIn(snippet, text)
def test_training_case_product_doc_reflects_current_m40_maturity(self) -> None:
text = TRAINING_PRODUCT_DOC.read_text(encoding="utf-8")
for snippet in (
CURRENT_TRAINING_DOC_MATURITY_MARKER,
"API contract coverage",
"error contract coverage",
"fixture/schema contract",
"offline checks registry smoke",
"public response privacy contract coverage",
"dashboard and public docs privacy smoke coverage",
):
with self.subTest(snippet=snippet):
self.assertIn(snippet, text)
for stale_snippet in ("M1-M25", "through M25", *TRAINING_M41_STALE_RELEASE_WORDING):
with self.subTest(stale_snippet=stale_snippet):
self.assertNotIn(stale_snippet, text)
def test_training_readmes_expose_m1_m40_release_index_without_raw_test_modules(self) -> None:
text_by_doc = {
path: path.read_text(encoding="utf-8")
for path in TRAINING_M41_RELEASE_INDEX_DOCS
}
missing_required_by_doc = _release_index_missing_required_snippets_by_doc(text_by_doc)
for path, text in text_by_doc.items():
for surface, _ in TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY:
missing_surface_snippets = tuple(
snippet
for missing_surface, snippet in missing_required_by_doc[path]
if missing_surface == surface
)
with self.subTest(path=path.name, surface=surface):
self.assertEqual(missing_surface_snippets, ())
with self.subTest(path=path.name, guard="stale_wording"):
for stale_snippet in TRAINING_M41_STALE_RELEASE_WORDING:
self.assertNotIn(stale_snippet, text)
with self.subTest(path=path.name, guard="raw_test_modules"):
self.assertIsNone(re.search(TRAINING_RAW_TEST_MODULE_PATTERN, text))
def test_training_case_m24_m29_documentation_test_inventory_is_current(self) -> None:
test_names = set(
_test_method_names_from_file(Path(__file__), "DocumentationConsistencyTests")
)
package_docs_test_names = set(
_test_method_names_from_file(TRAINING_DOCS_CLI_TEST, "TrainingCaseDocsCliM10Tests")
)
inventory_names = tuple(
name
for names in TRAINING_M24_M29_DOCUMENTATION_TEST_INVENTORY.values()
for name in names
)
unique_inventory_names = set(inventory_names)
text = TRAINING_PRODUCT_DOC.read_text(encoding="utf-8")
self.assertEqual(len(inventory_names), 8)
self.assertEqual(len(unique_inventory_names), 7)
self.assertEqual(sorted(TRAINING_M24_M29_DOCUMENTATION_TEST_INVENTORY), [
"dashboard_public_docs_privacy",
"m1_m40_maturity_wording",
"offline_registry_coverage",
"route_surface",
])
for surface, names in TRAINING_M24_M29_DOCUMENTATION_TEST_INVENTORY.items():
with self.subTest(surface=surface):
self.assertTrue(names)
for name in names:
self.assertIn(name, test_names)
self.assertIn(
TRAINING_M24_M29_PACKAGE_DOCS_INVENTORY_TEST,
package_docs_test_names,
)
self.assertIn(CURRENT_TRAINING_DOC_MATURITY_MARKER, text)
self.assertIn(CURRENT_TRAINING_DOC_MATURITY_SPAN, text)
def test_training_m41_release_index_guard_inventory_is_current(self) -> None:
module_path = Path(__file__)
module_source = module_path.read_text(encoding="utf-8")
test_names = set(
_test_method_names_from_file(module_path, "DocumentationConsistencyTests")
)
required_guard_tests_by_role = {
"docs_coverage": (
"test_training_readmes_expose_m1_m40_release_index_without_raw_test_modules"
),
"inventory_self_lock": (
"test_training_m41_release_index_guard_inventory_is_current"
),
"inventory_shape": "test_training_m41_release_index_inventory_shape_is_stable",
"per_doc_helper_self_lock": (
"test_training_m47_release_index_per_doc_helper_inventory_self_lock_is_current"
),
"per_doc_helper_tuple_shape": (
"test_training_m48_release_index_per_doc_helper_keeps_doc_tuple_shape"
),
"per_doc_helper_empty_docs": (
"test_training_m49_release_index_per_doc_helper_handles_empty_docs_without_mutation"
),
"per_doc_helper_flattened_complete_doc": (
"test_training_m50_release_index_helper_accepts_flattened_inventory_complete_doc"
),
"required_snippet_inventory_category_shape": (
"test_training_m54_release_index_required_snippet_inventory_category_shape_is_locked"
),
"required_snippet_inventory_source_shape": (
"test_training_m55_release_index_required_snippet_inventory_source_shape_is_locked"
),
"required_snippet_inventory_source_shape_negative_fixtures": (
"test_training_m56_release_index_required_snippet_inventory_source_shape_rejects_dynamic_fixtures"
),
"required_snippet_inventory_source_shape_diagnostics": (
"test_training_m57_release_index_required_snippet_inventory_source_shape_diagnostics_are_locked"
),
"required_snippet_inventory_source_shape_positive_fixtures": (
"test_training_m58_release_index_required_snippet_inventory_source_shape_accepts_literal_fixtures"
),
"required_snippet_inventory_source_shape_literal_order": (
"test_training_m59_release_index_required_snippet_inventory_source_shape_preserves_literal_order"
),
"required_snippet_inventory_source_shape_fixture_self_lock": (
"test_training_m60_release_index_source_shape_fixture_guard_inventory_self_lock_is_current"
),
"required_snippet_inventory_source_shape_fixture_constant_source_lock": (
"test_training_m61_release_index_source_shape_fixture_guard_methods_constant_source_shape_is_locked"
),
"required_snippet_inventory_source_shape_fixture_constant_negative_sources": (
"test_training_m62_release_index_source_shape_fixture_guard_methods_reject_dynamic_constant_sources"
),
"required_snippet_inventory_source_shape_fixture_constant_diagnostics": (
"test_training_m63_release_index_source_shape_fixture_guard_methods_constant_diagnostics_are_locked"
),
"required_snippet_inventory_source_shape_fixture_constant_positive_sources": (
"test_training_m64_release_index_source_shape_fixture_guard_methods_accept_valid_literal_sources"
),
"required_snippet_inventory_source_shape_fixture_constant_inventory_exactness": (
"test_training_m65_release_index_source_shape_fixture_guard_methods_constant_inventory_exactness_self_lock"
),
"required_snippet_inventory_source_shape_fixture_constant_source_exactness": (
"test_training_m66_release_index_source_shape_fixture_guard_methods_constant_source_exactness_self_lock"
),
"required_snippet_inventory_source_shape_fixture_constant_exactness_bridge": (
"test_training_m67_release_index_source_shape_fixture_guard_methods_constant_inventory_source_exactness_bridge_self_lock"
),
"required_snippet_inventory_source_shape_fixture_constant_exactness_bridge_duplicate_negative_fixture": (
"test_training_m69_release_index_source_shape_fixture_guard_methods_constant_inventory_source_exactness_bridge_duplicate_negative_fixture_self_lock"
),
"required_snippet_inventory_source_shape_fixture_constant_exactness_bridge_duplicate_guard_positive_diagnostic": (
"test_training_m70_release_index_source_shape_fixture_guard_methods_constant_inventory_source_exactness_bridge_duplicate_guard_positive_diagnostic_self_lock"
),
"required_snippet_inventory_source_shape_fixture_constant_exactness_bridge_triplet_source_shape": (
"test_training_m71_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_source_shape_self_lock"
),
"required_snippet_inventory_source_shape_fixture_constant_exactness_bridge_triplet_negative_sources": (
"test_training_m72_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_rejects_dynamic_sources"
),
"required_snippet_inventory_source_shape_fixture_constant_exactness_bridge_triplet_diagnostics": (
"test_training_m73_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostics_are_locked"
),
"required_snippet_inventory_source_shape_fixture_constant_exactness_bridge_triplet_diagnostic_fixture_inventory": (
"test_training_m74_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_self_lock"
),
"required_snippet_inventory_source_shape_fixture_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape": (
"test_training_m75_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_self_lock"
),
"required_snippet_inventory_source_shape_fixture_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_negative_sources": (
"test_training_m76_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_rejects_dynamic_sources"
),
"required_snippet_inventory_source_shape_fixture_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_edge_diagnostics": (
"test_training_m77_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_edge_diagnostics_are_locked"
),
"required_snippet_inventory_source_shape_fixture_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_positive_order_sources": (
"test_training_m78_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_accepts_ordered_literal_sources"
),
"required_snippet_inventory_source_shape_fixture_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster": (
"test_training_m79_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_self_lock"
),
"required_snippet_inventory_source_shape_fixture_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_negative_fixture": (
"test_training_m80_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_negative_fixture_self_lock"
),
"required_snippet_inventory_source_shape_fixture_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape": (
"test_training_m81_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_self_lock"
),
"required_snippet_inventory_source_shape_fixture_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_negative_sources": (
"test_training_m82_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_rejects_dynamic_sources"
),
"required_snippet_inventory_source_shape_fixture_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_edge_diagnostics": (
"test_training_m83_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_edge_diagnostics_are_locked"
),
"required_snippet_inventory_source_shape_fixture_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_inventory_self_lock": (
"test_training_m84_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_inventory_self_lock"
),
"release_index_public_docs_acceptance_inventory_alignment": (
"test_training_m85_release_index_public_docs_acceptance_inventory_alignment_self_lock"
),
"release_index_final_closure_delivery": (
"test_training_m86_release_index_final_closure_delivery_index_self_lock"
),
"release_index_final_closure_delivery_guard_self_lock": (
"test_training_m87_release_index_final_closure_delivery_index_guard_self_lock"
),
"release_index_final_closure_delivery_guard_source_self_lock": (
"test_training_m88_release_index_final_closure_delivery_guard_source_self_lock"
),
"release_index_final_closure_delivery_guard_source_chain_self_lock": (
"test_training_m89_release_index_final_closure_delivery_guard_source_chain_self_lock"
),
"release_index_final_closure_delivery_guard_source_chain_source_shape_self_lock": (
"test_training_m90_release_index_final_closure_delivery_guard_source_chain_source_shape_self_lock"
),
"release_index_final_closure_delivery_guard_source_chain_source_shape_local_names_self_lock": (
"test_training_m91_release_index_final_closure_delivery_guard_source_chain_source_shape_local_names_self_lock"
),
"release_index_final_closure_delivery_guard_source_chain_source_shape_local_names_registration_self_lock": (
"test_training_m92_release_index_final_closure_delivery_guard_source_chain_source_shape_local_names_registration_self_lock"
),
"per_doc_helper_exact_category_coverage": (
"test_training_m53_release_index_doc_category_coverage_is_exact"
),
"stale_wording": "test_training_case_product_doc_reflects_current_m40_maturity",
}
required_guard_tests = tuple(required_guard_tests_by_role.values())
required_release_snippets = (
CURRENT_TRAINING_DOC_MATURITY_MARKER,
CURRENT_TRAINING_DOC_MATURITY_SPAN,
CURRENT_TRAINING_DOC_MATURITY_PHRASE,
*TRAINING_ACCEPTANCE_VALIDATION_DOC_SNIPPETS,
"API contract coverage",
"error contract coverage",
"privacy contract coverage",
"package smoke",
"training_case_package",
"dashboard_js_syntax",
"dashboard and public docs privacy smoke coverage",
"single-set local Docker deployment",
"Docker smoke guard coverage",
)
required_stale_inventory_names = ("m1_m28_maturity_wording",)
required_stale_wording = ("M1-M39", "through M39", "through-M39")
expected_release_snippets = tuple(
snippet
for _, snippets in TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY
for snippet in snippets
)
active_release_inventory_values = "\n".join(
(
*TRAINING_M24_M29_DOCUMENTATION_TEST_INVENTORY,
*TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY,
*(
category
for category, _ in TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY
),
*TRAINING_M41_RELEASE_INDEX_DOC_SNIPPETS,
CURRENT_TRAINING_DOC_MATURITY_MARKER,
CURRENT_TRAINING_DOC_MATURITY_SPAN,
CURRENT_TRAINING_DOC_MATURITY_PHRASE,
)
)
guard_match = re.search(
rf"^ def {TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY[0]}"
r"\(.*?(?=^ def |\Z)",
module_source,
re.DOTALL | re.MULTILINE,
)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_DOCS,
(PROJECT_README, TRAINING_PRODUCT_DOC),
)
self.assertEqual(TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY, required_guard_tests)
self.assertEqual(len(required_guard_tests), len(set(required_guard_tests)))
self.assertEqual(
sorted(
category
for category, _ in TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY
),
[
"acceptance_offline_validation",
"current_m1_m40_marker",
"dashboard_public_docs_privacy",
"docker_smoke_guard_coverage",
"package_smoke_offline_registry",
"public_api_privacy_contracts",
"single_set_docker_deployment",
],
)
self.assertEqual(TRAINING_M41_RELEASE_INDEX_DOC_SNIPPETS, expected_release_snippets)
self.assertEqual(
TRAINING_M41_STALE_RELEASE_INVENTORY_NAMES,
required_stale_inventory_names,
)
self.assertEqual(TRAINING_M41_STALE_RELEASE_WORDING, required_stale_wording)
self.assertEqual(CURRENT_TRAINING_DOC_MATURITY_MARKER, "M1-M40")
self.assertEqual(CURRENT_TRAINING_DOC_MATURITY_SPAN, "through M40")
self.assertEqual(
CURRENT_TRAINING_DOC_MATURITY_PHRASE,
"current product maturity through M40",
)
for role, guard_test in required_guard_tests_by_role.items():
with self.subTest(release_index_guard=role):
loader = unittest.TestLoader()
suite = loader.loadTestsFromName(
f"{type(self).__module__}.DocumentationConsistencyTests.{guard_test}"
)
self.assertIn(guard_test, test_names)
self.assertEqual(loader.errors, [])
self.assertGreater(suite.countTestCases(), 0)
self.assertIsNotNone(guard_match)
guard_source = guard_match.group(0)
for guard_reference in (
"TRAINING_M41_RELEASE_INDEX_DOCS",
"TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY",
"_release_index_missing_required_snippets_by_doc",
"missing_required_by_doc[path]",
"TRAINING_M41_STALE_RELEASE_WORDING",
"TRAINING_RAW_TEST_MODULE_PATTERN",
):
with self.subTest(guard_reference=guard_reference):
self.assertIn(guard_reference, guard_source)
complete_release_doc = "\n".join(TRAINING_M41_RELEASE_INDEX_DOC_SNIPPETS)
missing_surface, missing_snippet = next(
(surface, snippets[0])
for surface, snippets in TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY
)
missing_release_doc = complete_release_doc.replace(missing_snippet, "", 1)
negative_fixture_missing_by_doc = _release_index_missing_required_snippets_by_doc(
{
PROJECT_README: missing_release_doc,
TRAINING_PRODUCT_DOC: complete_release_doc,
}
)
self.assertEqual(negative_fixture_missing_by_doc[TRAINING_PRODUCT_DOC], ())
self.assertEqual(
negative_fixture_missing_by_doc[PROJECT_README],
((missing_surface, missing_snippet),),
)
for surface, snippets in TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY:
with self.subTest(surface=surface):
self.assertTrue(snippets)
for snippet in required_release_snippets:
with self.subTest(snippet=snippet):
self.assertIn(snippet, TRAINING_M41_RELEASE_INDEX_DOC_SNIPPETS)
for stale_value in (
*required_stale_inventory_names,
*required_stale_wording,
):
with self.subTest(stale_value=stale_value):
self.assertNotIn(stale_value, active_release_inventory_values)
def test_training_m52_release_index_guard_inventory_order_and_uniqueness_self_lock(self) -> None:
expected_inventory = (
"test_training_readmes_expose_m1_m40_release_index_without_raw_test_modules",
"test_training_m41_release_index_guard_inventory_is_current",
"test_training_m41_release_index_inventory_shape_is_stable",
"test_training_m47_release_index_per_doc_helper_inventory_self_lock_is_current",
"test_training_m48_release_index_per_doc_helper_keeps_doc_tuple_shape",
"test_training_m49_release_index_per_doc_helper_handles_empty_docs_without_mutation",
"test_training_m50_release_index_helper_accepts_flattened_inventory_complete_doc",
"test_training_m54_release_index_required_snippet_inventory_category_shape_is_locked",
"test_training_m55_release_index_required_snippet_inventory_source_shape_is_locked",
"test_training_m56_release_index_required_snippet_inventory_source_shape_rejects_dynamic_fixtures",
"test_training_m57_release_index_required_snippet_inventory_source_shape_diagnostics_are_locked",
"test_training_m58_release_index_required_snippet_inventory_source_shape_accepts_literal_fixtures",
"test_training_m59_release_index_required_snippet_inventory_source_shape_preserves_literal_order",
"test_training_m60_release_index_source_shape_fixture_guard_inventory_self_lock_is_current",
"test_training_m61_release_index_source_shape_fixture_guard_methods_constant_source_shape_is_locked",
"test_training_m62_release_index_source_shape_fixture_guard_methods_reject_dynamic_constant_sources",
"test_training_m63_release_index_source_shape_fixture_guard_methods_constant_diagnostics_are_locked",
"test_training_m64_release_index_source_shape_fixture_guard_methods_accept_valid_literal_sources",
"test_training_m65_release_index_source_shape_fixture_guard_methods_constant_inventory_exactness_self_lock",
"test_training_m66_release_index_source_shape_fixture_guard_methods_constant_source_exactness_self_lock",
"test_training_m67_release_index_source_shape_fixture_guard_methods_constant_inventory_source_exactness_bridge_self_lock",
"test_training_m69_release_index_source_shape_fixture_guard_methods_constant_inventory_source_exactness_bridge_duplicate_negative_fixture_self_lock",
"test_training_m70_release_index_source_shape_fixture_guard_methods_constant_inventory_source_exactness_bridge_duplicate_guard_positive_diagnostic_self_lock",
"test_training_m71_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_source_shape_self_lock",
"test_training_m72_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_rejects_dynamic_sources",
"test_training_m73_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostics_are_locked",
"test_training_m74_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_self_lock",
"test_training_m75_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_self_lock",
"test_training_m76_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_rejects_dynamic_sources",
"test_training_m77_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_edge_diagnostics_are_locked",
"test_training_m78_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_accepts_ordered_literal_sources",
"test_training_m79_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_self_lock",
"test_training_m80_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_negative_fixture_self_lock",
"test_training_m81_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_self_lock",
"test_training_m82_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_rejects_dynamic_sources",
"test_training_m83_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_edge_diagnostics_are_locked",
"test_training_m84_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_inventory_self_lock",
"test_training_m85_release_index_public_docs_acceptance_inventory_alignment_self_lock",
"test_training_m86_release_index_final_closure_delivery_index_self_lock",
"test_training_m87_release_index_final_closure_delivery_index_guard_self_lock",
"test_training_m88_release_index_final_closure_delivery_guard_source_self_lock",
"test_training_m89_release_index_final_closure_delivery_guard_source_chain_self_lock",
"test_training_m90_release_index_final_closure_delivery_guard_source_chain_source_shape_self_lock",
"test_training_m91_release_index_final_closure_delivery_guard_source_chain_source_shape_local_names_self_lock",
"test_training_m92_release_index_final_closure_delivery_guard_source_chain_source_shape_local_names_registration_self_lock",
"test_training_m53_release_index_doc_category_coverage_is_exact",
"test_training_case_product_doc_reflects_current_m40_maturity",
)
helper_guard_sequence = (
"test_training_m47_release_index_per_doc_helper_inventory_self_lock_is_current",
"test_training_m48_release_index_per_doc_helper_keeps_doc_tuple_shape",
"test_training_m49_release_index_per_doc_helper_handles_empty_docs_without_mutation",
"test_training_m50_release_index_helper_accepts_flattened_inventory_complete_doc",
)
test_case_name = f"{type(self).__module__}.{type(self).__qualname__}"
self.assertEqual(TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY, expected_inventory)
self.assertEqual(
len(TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY),
len(set(TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)),
)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY[3:7],
helper_guard_sequence,
)
for method_name in TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY:
with self.subTest(method_name=method_name):
loader = unittest.TestLoader()
suite = loader.loadTestsFromName(f"{test_case_name}.{method_name}")
self.assertEqual(loader.errors, [])
self.assertEqual(suite.countTestCases(), 1)
def test_training_m60_release_index_source_shape_fixture_guard_inventory_self_lock_is_current(
self,
) -> None:
expected_source_shape_fixture_guards = (
"test_training_m55_release_index_required_snippet_inventory_source_shape_is_locked",
"test_training_m56_release_index_required_snippet_inventory_source_shape_rejects_dynamic_fixtures",
"test_training_m57_release_index_required_snippet_inventory_source_shape_diagnostics_are_locked",
"test_training_m58_release_index_required_snippet_inventory_source_shape_accepts_literal_fixtures",
"test_training_m59_release_index_required_snippet_inventory_source_shape_preserves_literal_order",
"test_training_m60_release_index_source_shape_fixture_guard_inventory_self_lock_is_current",
"test_training_m61_release_index_source_shape_fixture_guard_methods_constant_source_shape_is_locked",
"test_training_m62_release_index_source_shape_fixture_guard_methods_reject_dynamic_constant_sources",
"test_training_m63_release_index_source_shape_fixture_guard_methods_constant_diagnostics_are_locked",
"test_training_m64_release_index_source_shape_fixture_guard_methods_accept_valid_literal_sources",
)
expected_literal_source_shape_fixture_guards = (
expected_source_shape_fixture_guards[:5]
)
test_case_name = f"{type(self).__module__}.{type(self).__qualname__}"
self_lock_name = (
"test_training_m60_release_index_source_shape_fixture_guard_inventory_self_lock_is_current"
)
source_shape_inventory_start = (
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
expected_source_shape_fixture_guards[0]
)
)
source_shape_inventory_end = source_shape_inventory_start + len(
expected_source_shape_fixture_guards
)
discovered_method_names = _test_method_names_from_file(
Path(__file__),
"DocumentationConsistencyTests",
)
source_shape_start = discovered_method_names.index(
expected_literal_source_shape_fixture_guards[0]
)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_SOURCE_SHAPE_FIXTURE_GUARD_METHODS,
expected_source_shape_fixture_guards,
)
self.assertEqual(
len(TRAINING_M41_RELEASE_INDEX_SOURCE_SHAPE_FIXTURE_GUARD_METHODS),
len(set(TRAINING_M41_RELEASE_INDEX_SOURCE_SHAPE_FIXTURE_GUARD_METHODS)),
)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY[
source_shape_inventory_start:source_shape_inventory_end
],
TRAINING_M41_RELEASE_INDEX_SOURCE_SHAPE_FIXTURE_GUARD_METHODS,
)
self.assertEqual(
discovered_method_names[
source_shape_start : source_shape_start
+ len(expected_literal_source_shape_fixture_guards)
],
expected_literal_source_shape_fixture_guards,
)
self.assertIn(self_lock_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
for method_name in TRAINING_M41_RELEASE_INDEX_SOURCE_SHAPE_FIXTURE_GUARD_METHODS:
with self.subTest(method_name=method_name):
loader = unittest.TestLoader()
suite = loader.loadTestsFromName(f"{test_case_name}.{method_name}")
self.assertEqual(loader.errors, [])
self.assertEqual(suite.countTestCases(), 1)
@staticmethod
def _release_index_source_shape_fixture_guard_method_names_from_source(
module_source: str,
) -> tuple[str, ...]:
constant_name = "TRAINING_M41_RELEASE_INDEX_SOURCE_SHAPE_FIXTURE_GUARD_METHODS"
module_tree = ast.parse(module_source)
constant_assignments = tuple(
node
for node in module_tree.body
if isinstance(node, ast.Assign)
and len(node.targets) == 1
and isinstance(node.targets[0], ast.Name)
and node.targets[0].id == constant_name
)
if len(constant_assignments) != 1:
raise AssertionError(
"source shape fixture guard methods must have one assignment"
)
constant_source = constant_assignments[0].value
disallowed_source_nodes = (
ast.Call,
ast.DictComp,
ast.GeneratorExp,
ast.List,
ast.ListComp,
ast.Name,
ast.SetComp,
ast.Starred,
)
dynamic_source_node = next(
(
node
for node in ast.walk(constant_source)
if isinstance(node, disallowed_source_nodes)
),
None,
)
if dynamic_source_node is not None:
dynamic_node = type(dynamic_source_node).__name__
raise AssertionError(
"source shape fixture guard methods use dynamic source node "
f"{dynamic_node}"
)
if not isinstance(constant_source, ast.Tuple):
raise AssertionError(
"source shape fixture guard methods must be a literal tuple assignment"
)
if not constant_source.elts or not all(
isinstance(element, ast.Constant) and isinstance(element.value, str)
for element in constant_source.elts
):
raise AssertionError(
"source shape fixture guard methods must use literal method names"
)
try:
method_names = ast.literal_eval(constant_source)
except (SyntaxError, ValueError) as exc:
raise AssertionError(
"source shape fixture guard methods must use literal method names"
) from exc
if not all(isinstance(method_name, str) for method_name in method_names):
raise AssertionError(
"source shape fixture guard methods must use literal method names"
)
return method_names
def test_training_m61_release_index_source_shape_fixture_guard_methods_constant_source_shape_is_locked(
self,
) -> None:
expected_source_shape_fixture_guards = (
"test_training_m55_release_index_required_snippet_inventory_source_shape_is_locked",
"test_training_m56_release_index_required_snippet_inventory_source_shape_rejects_dynamic_fixtures",
"test_training_m57_release_index_required_snippet_inventory_source_shape_diagnostics_are_locked",
"test_training_m58_release_index_required_snippet_inventory_source_shape_accepts_literal_fixtures",
"test_training_m59_release_index_required_snippet_inventory_source_shape_preserves_literal_order",
"test_training_m60_release_index_source_shape_fixture_guard_inventory_self_lock_is_current",
"test_training_m61_release_index_source_shape_fixture_guard_methods_constant_source_shape_is_locked",
"test_training_m62_release_index_source_shape_fixture_guard_methods_reject_dynamic_constant_sources",
"test_training_m63_release_index_source_shape_fixture_guard_methods_constant_diagnostics_are_locked",
"test_training_m64_release_index_source_shape_fixture_guard_methods_accept_valid_literal_sources",
)
module_source = Path(__file__).read_text(encoding="utf-8")
self.assertEqual(
self._release_index_source_shape_fixture_guard_method_names_from_source(
module_source
),
expected_source_shape_fixture_guards,
)
def test_training_m62_release_index_source_shape_fixture_guard_methods_reject_dynamic_constant_sources(
self,
) -> None:
constant_name = "TRAINING_M41_RELEASE_INDEX_SOURCE_SHAPE_FIXTURE_GUARD_METHODS"
first_method = (
"test_training_m55_release_index_required_snippet_inventory_source_shape_is_locked"
)
second_method = (
"test_training_m56_release_index_required_snippet_inventory_source_shape_rejects_dynamic_fixtures"
)
invalid_sources = {
"tuple_call": (
f"{constant_name} = tuple([{first_method!r}, {second_method!r}])",
"dynamic source node Call",
),
"sorted_call": (
f"{constant_name} = sorted(({first_method!r}, {second_method!r}))",
"dynamic source node Call",
),
"name_alias": (
f"fixture_guard_methods = ({first_method!r}, {second_method!r})\n"
f"{constant_name} = fixture_guard_methods",
"dynamic source node Name",
),
"list_literal": (
f"{constant_name} = [{first_method!r}, {second_method!r}]",
"dynamic source node List",
),
"list_comprehension": (
f"{constant_name} = [method for method in ({first_method!r}, {second_method!r})]",
"dynamic source node ListComp",
),
}
for fixture_name, (source, error_snippet) in invalid_sources.items():
with self.subTest(fixture_name=fixture_name):
with self.assertRaisesRegex(AssertionError, re.escape(error_snippet)):
self._release_index_source_shape_fixture_guard_method_names_from_source(
source
)
def test_training_m63_release_index_source_shape_fixture_guard_methods_constant_diagnostics_are_locked(
self,
) -> None:
constant_name = "TRAINING_M41_RELEASE_INDEX_SOURCE_SHAPE_FIXTURE_GUARD_METHODS"
guard_name = (
"test_training_m63_release_index_source_shape_fixture_guard_methods_constant_diagnostics_are_locked"
)
invalid_sources = {
"missing_constant_assignment": (
"UNRELATED_FIXTURE_GUARD_METHODS = ('literal_method_alpha',)",
"must have one assignment",
),
"duplicate_constant_assignment": (
f"{constant_name} = ('literal_method_alpha',)\n"
f"{constant_name} = ('literal_method_beta',)",
"must have one assignment",
),
"empty_tuple_assignment": (
f"{constant_name} = ()",
"must use literal method names",
),
"integer_method_name": (
f"{constant_name} = ('literal_method_alpha', 123)",
"must use literal method names",
),
"none_method_name": (
f"{constant_name} = ('literal_method_alpha', None)",
"must use literal method names",
),
}
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
for fixture_name, (source, error_snippet) in invalid_sources.items():
with self.subTest(fixture_name=fixture_name):
with self.assertRaisesRegex(AssertionError, re.escape(error_snippet)):
self._release_index_source_shape_fixture_guard_method_names_from_source(
source
)
def test_training_m64_release_index_source_shape_fixture_guard_methods_accept_valid_literal_sources(
self,
) -> None:
constant_name = "TRAINING_M41_RELEASE_INDEX_SOURCE_SHAPE_FIXTURE_GUARD_METHODS"
guard_name = (
"test_training_m64_release_index_source_shape_fixture_guard_methods_accept_valid_literal_sources"
)
expected_literal_order = (
"literal_method_gamma",
"literal_method_alpha",
"literal_method_beta",
)
ordered_source = f"""
{constant_name} = (
{expected_literal_order[0]!r},
{expected_literal_order[1]!r},
{expected_literal_order[2]!r},
)
"""
single_item_source = f"{constant_name} = ('literal_method_single',)"
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
source_method_names = (
self._release_index_source_shape_fixture_guard_method_names_from_source(
ordered_source
)
)
self.assertEqual(source_method_names, expected_literal_order)
self.assertNotEqual(source_method_names, tuple(sorted(source_method_names)))
self.assertEqual(
self._release_index_source_shape_fixture_guard_method_names_from_source(
single_item_source
),
("literal_method_single",),
)
def test_training_m65_release_index_source_shape_fixture_guard_methods_constant_inventory_exactness_self_lock(
self,
) -> None:
expected_source_shape_fixture_guards = (
"test_training_m55_release_index_required_snippet_inventory_source_shape_is_locked",
"test_training_m56_release_index_required_snippet_inventory_source_shape_rejects_dynamic_fixtures",
"test_training_m57_release_index_required_snippet_inventory_source_shape_diagnostics_are_locked",
"test_training_m58_release_index_required_snippet_inventory_source_shape_accepts_literal_fixtures",
"test_training_m59_release_index_required_snippet_inventory_source_shape_preserves_literal_order",
"test_training_m60_release_index_source_shape_fixture_guard_inventory_self_lock_is_current",
"test_training_m61_release_index_source_shape_fixture_guard_methods_constant_source_shape_is_locked",
"test_training_m62_release_index_source_shape_fixture_guard_methods_reject_dynamic_constant_sources",
"test_training_m63_release_index_source_shape_fixture_guard_methods_constant_diagnostics_are_locked",
"test_training_m64_release_index_source_shape_fixture_guard_methods_accept_valid_literal_sources",
)
guard_name = (
"test_training_m65_release_index_source_shape_fixture_guard_methods_constant_inventory_exactness_self_lock"
)
test_case_name = f"{type(self).__module__}.{type(self).__qualname__}"
source_shape_start = TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
expected_source_shape_fixture_guards[0]
)
source_shape_end = source_shape_start + len(expected_source_shape_fixture_guards)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_SOURCE_SHAPE_FIXTURE_GUARD_METHODS,
expected_source_shape_fixture_guards,
)
self.assertEqual(
len(TRAINING_M41_RELEASE_INDEX_SOURCE_SHAPE_FIXTURE_GUARD_METHODS),
len(set(TRAINING_M41_RELEASE_INDEX_SOURCE_SHAPE_FIXTURE_GUARD_METHODS)),
)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY[
source_shape_start:source_shape_end
],
TRAINING_M41_RELEASE_INDEX_SOURCE_SHAPE_FIXTURE_GUARD_METHODS,
)
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
for method_name in TRAINING_M41_RELEASE_INDEX_SOURCE_SHAPE_FIXTURE_GUARD_METHODS:
with self.subTest(method_name=method_name):
loader = unittest.TestLoader()
suite = loader.loadTestsFromName(f"{test_case_name}.{method_name}")
self.assertEqual(loader.errors, [])
self.assertEqual(suite.countTestCases(), 1)
def test_training_m66_release_index_source_shape_fixture_guard_methods_constant_source_exactness_self_lock(
self,
) -> None:
expected_source_shape_fixture_guards = (
"test_training_m55_release_index_required_snippet_inventory_source_shape_is_locked",
"test_training_m56_release_index_required_snippet_inventory_source_shape_rejects_dynamic_fixtures",
"test_training_m57_release_index_required_snippet_inventory_source_shape_diagnostics_are_locked",
"test_training_m58_release_index_required_snippet_inventory_source_shape_accepts_literal_fixtures",
"test_training_m59_release_index_required_snippet_inventory_source_shape_preserves_literal_order",
"test_training_m60_release_index_source_shape_fixture_guard_inventory_self_lock_is_current",
"test_training_m61_release_index_source_shape_fixture_guard_methods_constant_source_shape_is_locked",
"test_training_m62_release_index_source_shape_fixture_guard_methods_reject_dynamic_constant_sources",
"test_training_m63_release_index_source_shape_fixture_guard_methods_constant_diagnostics_are_locked",
"test_training_m64_release_index_source_shape_fixture_guard_methods_accept_valid_literal_sources",
)
guard_name = (
"test_training_m66_release_index_source_shape_fixture_guard_methods_constant_source_exactness_self_lock"
)
module_source = Path(__file__).read_text(encoding="utf-8")
source_method_names = (
self._release_index_source_shape_fixture_guard_method_names_from_source(
module_source
)
)
self.assertEqual(
source_method_names,
TRAINING_M41_RELEASE_INDEX_SOURCE_SHAPE_FIXTURE_GUARD_METHODS,
)
self.assertEqual(source_method_names, expected_source_shape_fixture_guards)
self.assertEqual(len(source_method_names), len(set(source_method_names)))
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
def test_training_m67_release_index_source_shape_fixture_guard_methods_constant_inventory_source_exactness_bridge_self_lock(
self,
) -> None:
exactness_bridge_guard_names = (
TRAINING_M41_RELEASE_INDEX_EXACTNESS_BRIDGE_GUARD_METHODS
)
(
inventory_exactness_guard,
source_exactness_guard,
guard_name,
) = exactness_bridge_guard_names
test_case_name = f"{type(self).__module__}.{type(self).__qualname__}"
for method_name in exactness_bridge_guard_names:
with self.subTest(method_name=method_name):
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.count(method_name),
1,
)
loader = unittest.TestLoader()
suite = loader.loadTestsFromName(f"{test_case_name}.{method_name}")
self.assertEqual(loader.errors, [])
self.assertEqual(suite.countTestCases(), 1)
inventory_exactness_index = (
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
inventory_exactness_guard
)
)
source_exactness_index = (
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
source_exactness_guard
)
)
bridge_exactness_index = TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
guard_name
)
self.assertEqual(source_exactness_index, inventory_exactness_index + 1)
self.assertEqual(bridge_exactness_index, source_exactness_index + 1)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY[
inventory_exactness_index : bridge_exactness_index + 1
],
exactness_bridge_guard_names,
)
def test_training_m69_release_index_source_shape_fixture_guard_methods_constant_inventory_source_exactness_bridge_duplicate_negative_fixture_self_lock(
self,
) -> None:
guard_name = (
"test_training_m69_release_index_source_shape_fixture_guard_methods_constant_inventory_source_exactness_bridge_duplicate_negative_fixture_self_lock"
)
exactness_bridge_guard_names = (
TRAINING_M41_RELEASE_INDEX_EXACTNESS_BRIDGE_GUARD_METHODS
)
bridge_exactness_guard = exactness_bridge_guard_names[-1]
synthetic_duplicate_inventory = (
*TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY,
bridge_exactness_guard,
)
exact_once_counts = tuple(
synthetic_duplicate_inventory.count(method_name)
for method_name in exactness_bridge_guard_names
)
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
self.assertEqual(
synthetic_duplicate_inventory[:-1],
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY,
)
self.assertNotEqual(exact_once_counts, (1, 1, 1))
self.assertEqual(exact_once_counts, (1, 1, 2))
def test_training_m70_release_index_source_shape_fixture_guard_methods_constant_inventory_source_exactness_bridge_duplicate_guard_positive_diagnostic_self_lock(
self,
) -> None:
guard_name = (
"test_training_m70_release_index_source_shape_fixture_guard_methods_constant_inventory_source_exactness_bridge_duplicate_guard_positive_diagnostic_self_lock"
)
exactness_bridge_guard_names = (
TRAINING_M41_RELEASE_INDEX_EXACTNESS_BRIDGE_GUARD_METHODS
)
exact_once_counts = tuple(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.count(method_name)
for method_name in exactness_bridge_guard_names
)
bridge_start = TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
exactness_bridge_guard_names[0]
)
bridge_indices = tuple(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(method_name)
for method_name in exactness_bridge_guard_names
)
test_case_name = f"{type(self).__module__}.{type(self).__qualname__}"
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
self.assertEqual(exact_once_counts, (1, 1, 1))
self.assertEqual(
bridge_indices,
tuple(range(bridge_start, bridge_start + len(exactness_bridge_guard_names))),
)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY[
bridge_start : bridge_start + len(exactness_bridge_guard_names)
],
exactness_bridge_guard_names,
)
for method_name in exactness_bridge_guard_names:
with self.subTest(method_name=method_name):
loader = unittest.TestLoader()
suite = loader.loadTestsFromName(f"{test_case_name}.{method_name}")
self.assertEqual(loader.errors, [])
self.assertEqual(suite.countTestCases(), 1)
@staticmethod
def _release_index_exactness_bridge_guard_method_names_from_source(
module_source: str,
) -> tuple[str, ...]:
constant_name = "TRAINING_M41_RELEASE_INDEX_EXACTNESS_BRIDGE_GUARD_METHODS"
module_tree = ast.parse(module_source)
top_level_writes = tuple(
node
for node in module_tree.body
if (
isinstance(node, ast.Assign)
and any(
isinstance(target, ast.Name) and target.id == constant_name
for target in node.targets
)
)
or (
isinstance(node, (ast.AnnAssign, ast.AugAssign))
and isinstance(node.target, ast.Name)
and node.target.id == constant_name
)
)
if len(top_level_writes) != 1:
raise AssertionError("exactness bridge guard methods must have one assignment")
constant_assignment = top_level_writes[0]
if (
not isinstance(constant_assignment, ast.Assign)
or len(constant_assignment.targets) != 1
or not isinstance(constant_assignment.targets[0], ast.Name)
or constant_assignment.targets[0].id != constant_name
):
raise AssertionError(
"exactness bridge guard methods must use one simple assignment"
)
constant_source = constant_assignment.value
disallowed_source_node_types = (
ast.Call,
ast.DictComp,
ast.GeneratorExp,
ast.List,
ast.ListComp,
ast.Name,
ast.SetComp,
ast.Starred,
)
dynamic_source_node = next(
(
node
for node in ast.walk(constant_source)
if isinstance(node, disallowed_source_node_types)
),
None,
)
if dynamic_source_node is not None:
dynamic_node = type(dynamic_source_node).__name__
raise AssertionError(
"exactness bridge guard methods use dynamic source node "
f"{dynamic_node}"
)
if not isinstance(constant_source, ast.Tuple) or len(constant_source.elts) != 3:
raise AssertionError(
"exactness bridge guard methods must be a literal triplet tuple assignment"
)
if not all(
isinstance(element, ast.Constant) and isinstance(element.value, str)
for element in constant_source.elts
):
raise AssertionError(
"exactness bridge guard methods must use literal method names"
)
try:
method_names = ast.literal_eval(constant_source)
except (SyntaxError, ValueError) as exc:
raise AssertionError(
"exactness bridge guard methods must use literal method names"
) from exc
if (
not isinstance(method_names, tuple)
or len(method_names) != 3
or not all(isinstance(method_name, str) for method_name in method_names)
):
raise AssertionError(
"exactness bridge guard methods must use literal method names"
)
return method_names
def test_training_m71_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_source_shape_self_lock(
self,
) -> None:
guard_name = (
"test_training_m71_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_source_shape_self_lock"
)
expected_bridge_methods = (
"test_training_m65_release_index_source_shape_fixture_guard_methods_constant_inventory_exactness_self_lock",
"test_training_m66_release_index_source_shape_fixture_guard_methods_constant_source_exactness_self_lock",
"test_training_m67_release_index_source_shape_fixture_guard_methods_constant_inventory_source_exactness_bridge_self_lock",
)
module_source = Path(__file__).read_text(encoding="utf-8")
source_bridge_methods = (
self._release_index_exactness_bridge_guard_method_names_from_source(
module_source
)
)
self.assertEqual(
source_bridge_methods,
TRAINING_M41_RELEASE_INDEX_EXACTNESS_BRIDGE_GUARD_METHODS,
)
self.assertEqual(source_bridge_methods, expected_bridge_methods)
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
def test_training_m72_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_rejects_dynamic_sources(
self,
) -> None:
constant_name = "TRAINING_M41_RELEASE_INDEX_EXACTNESS_BRIDGE_GUARD_METHODS"
guard_name = (
"test_training_m72_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_rejects_dynamic_sources"
)
first_method = (
"test_training_m65_release_index_source_shape_fixture_guard_methods_constant_inventory_exactness_self_lock"
)
second_method = (
"test_training_m66_release_index_source_shape_fixture_guard_methods_constant_source_exactness_self_lock"
)
third_method = (
"test_training_m67_release_index_source_shape_fixture_guard_methods_constant_inventory_source_exactness_bridge_self_lock"
)
invalid_sources = {
"list_literal": (
f"{constant_name} = [{first_method!r}, {second_method!r}, {third_method!r}]",
"dynamic source node List",
),
"name_alias": (
f"bridge_methods = ({first_method!r}, {second_method!r}, {third_method!r})\n"
f"{constant_name} = bridge_methods",
"dynamic source node Name",
),
"tuple_call": (
f"{constant_name} = tuple(({first_method!r}, {second_method!r}, {third_method!r}))",
"dynamic source node Call",
),
"starred_tuple": (
f"{constant_name} = ({first_method!r}, *({second_method!r},), {third_method!r})",
"dynamic source node Starred",
),
"list_comprehension": (
f"{constant_name} = "
f"[method for method in ({first_method!r}, {second_method!r}, {third_method!r})]",
"dynamic source node ListComp",
),
"generator_expression": (
f"{constant_name} = "
f"(method for method in ({first_method!r}, {second_method!r}, {third_method!r}))",
"dynamic source node GeneratorExp",
),
}
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
for fixture_name, (source, error_snippet) in invalid_sources.items():
with self.subTest(fixture_name=fixture_name):
with self.assertRaisesRegex(AssertionError, re.escape(error_snippet)):
self._release_index_exactness_bridge_guard_method_names_from_source(
source
)
def test_training_m73_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostics_are_locked(
self,
) -> None:
constant_name = "TRAINING_M41_RELEASE_INDEX_EXACTNESS_BRIDGE_GUARD_METHODS"
guard_name = (
"test_training_m73_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostics_are_locked"
)
literal_methods = (
"literal_bridge_alpha",
"literal_bridge_beta",
"literal_bridge_gamma",
)
valid_triplet_source = (
f"({literal_methods[0]!r}, {literal_methods[1]!r}, "
f"{literal_methods[2]!r})"
)
invalid_sources = {
"missing_assignment": (
"UNRELATED_BRIDGE_GUARD_METHODS = ('literal_bridge_alpha',)",
"must have one assignment",
),
"duplicate_top_level_assignment": (
f"{constant_name} = {valid_triplet_source}\n"
f"{constant_name} = {valid_triplet_source}",
"must have one assignment",
),
"multiple_assignment_targets": (
f"{constant_name} = bridge_methods = {valid_triplet_source}",
"must use one simple assignment",
),
"empty_tuple": (
f"{constant_name} = ()",
"must be a literal triplet tuple assignment",
),
"two_item_tuple": (
f"{constant_name} = ({literal_methods[0]!r}, {literal_methods[1]!r})",
"must be a literal triplet tuple assignment",
),
"four_item_tuple": (
f"{constant_name} = ("
f"{literal_methods[0]!r}, {literal_methods[1]!r}, "
f"{literal_methods[2]!r}, 'literal_bridge_delta')",
"must be a literal triplet tuple assignment",
),
"integer_literal_method_name": (
f"{constant_name} = ({literal_methods[0]!r}, 123, {literal_methods[2]!r})",
"must use literal method names",
),
"none_literal_method_name": (
f"{constant_name} = ({literal_methods[0]!r}, None, {literal_methods[2]!r})",
"must use literal method names",
),
}
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
for fixture_name, (source, error_snippet) in invalid_sources.items():
with self.subTest(fixture_name=fixture_name):
with self.assertRaisesRegex(AssertionError, re.escape(error_snippet)):
self._release_index_exactness_bridge_guard_method_names_from_source(
source
)
def test_training_m74_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_self_lock(
self,
) -> None:
guard_name = (
"test_training_m74_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_self_lock"
)
m73_guard_name = (
"test_training_m73_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostics_are_locked"
)
expected_fixture_diagnostics = (
("missing_assignment", "must have one assignment"),
("duplicate_top_level_assignment", "must have one assignment"),
("multiple_assignment_targets", "must use one simple assignment"),
(
"empty_tuple",
"must be a literal triplet tuple assignment",
),
(
"two_item_tuple",
"must be a literal triplet tuple assignment",
),
(
"four_item_tuple",
"must be a literal triplet tuple assignment",
),
("integer_literal_method_name", "must use literal method names"),
("none_literal_method_name", "must use literal method names"),
)
allowed_diagnostic_snippets = (
"must have one assignment",
"must use one simple assignment",
"must be a literal triplet tuple assignment",
"must use literal method names",
)
module_source = Path(__file__).read_text(encoding="utf-8")
module_tree = ast.parse(module_source)
m73_methods = tuple(
node
for node in ast.walk(module_tree)
if isinstance(node, ast.FunctionDef) and node.name == m73_guard_name
)
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
self.assertEqual(len(m73_methods), 1)
m73_method = m73_methods[0]
invalid_source_assignments = tuple(
node
for node in ast.walk(m73_method)
if (
isinstance(node, ast.Assign)
and len(node.targets) == 1
and isinstance(node.targets[0], ast.Name)
and node.targets[0].id == "invalid_sources"
)
)
self.assertEqual(len(invalid_source_assignments), 1)
invalid_sources = invalid_source_assignments[0].value
self.assertIsInstance(invalid_sources, ast.Dict)
fixture_diagnostics = tuple(
(fixture_key.value, fixture_value.elts[1].value)
for fixture_key, fixture_value in zip(
invalid_sources.keys,
invalid_sources.values,
)
)
fixture_names = tuple(name for name, _ in fixture_diagnostics)
self.assertEqual(fixture_diagnostics, expected_fixture_diagnostics)
self.assertEqual(len(fixture_names), len(set(fixture_names)))
for fixture_name, diagnostic_snippet in fixture_diagnostics:
with self.subTest(fixture_name=fixture_name):
self.assertTrue(diagnostic_snippet)
self.assertIn(diagnostic_snippet, allowed_diagnostic_snippets)
invalid_source_loops = tuple(
node
for node in ast.walk(m73_method)
if (
isinstance(node, ast.For)
and isinstance(node.iter, ast.Call)
and isinstance(node.iter.func, ast.Attribute)
and node.iter.func.attr == "items"
and isinstance(node.iter.func.value, ast.Name)
and node.iter.func.value.id == "invalid_sources"
)
)
self.assertEqual(len(invalid_source_loops), 1)
invalid_source_loop = (
ast.get_source_segment(module_source, invalid_source_loops[0])
or ""
)
for loop_reference in (
"fixture_name, (source, error_snippet)",
"self.subTest(fixture_name=fixture_name)",
"_release_index_exactness_bridge_guard_method_names_from_source",
):
with self.subTest(loop_reference=loop_reference):
self.assertIn(loop_reference, invalid_source_loop)
@staticmethod
def _release_index_m74_diagnostic_fixture_inventory_source_nodes(
m74_method: ast.FunctionDef,
) -> tuple[ast.Tuple, ast.Tuple]:
local_names = (
"expected_fixture_diagnostics",
"allowed_diagnostic_snippets",
)
disallowed_source_node_types = (
ast.BinOp,
ast.Call,
ast.Dict,
ast.DictComp,
ast.GeneratorExp,
ast.List,
ast.ListComp,
ast.Name,
ast.Set,
ast.SetComp,
ast.Starred,
)
source_nodes = []
for local_name in local_names:
def local_write(node: ast.AST) -> bool:
if isinstance(node, ast.Assign):
targets = node.targets
elif isinstance(node, (ast.AnnAssign, ast.AugAssign)):
targets = (node.target,)
else:
return False
return any(
isinstance(target, ast.Name) and target.id == local_name
for target in targets
)
writes = tuple(
node for node in ast.walk(m74_method) if local_write(node)
)
if len(writes) != 1:
raise AssertionError(
"diagnostic fixture inventory source shape must have one "
f"{local_name} assignment"
)
assignment = writes[0]
if (
not isinstance(assignment, ast.Assign)
or len(assignment.targets) != 1
or not isinstance(assignment.targets[0], ast.Name)
or assignment.targets[0].id != local_name
):
raise AssertionError(
"diagnostic fixture inventory source shape must use one "
f"simple {local_name} assignment"
)
source_node = assignment.value
dynamic_source_node = next(
(
node
for node in ast.walk(source_node)
if isinstance(node, disallowed_source_node_types)
),
None,
)
if dynamic_source_node is not None:
dynamic_node = type(dynamic_source_node).__name__
raise AssertionError(
"diagnostic fixture inventory source shape uses dynamic "
f"source node {dynamic_node}"
)
if not isinstance(source_node, ast.Tuple) or not source_node.elts:
raise AssertionError(
"diagnostic fixture inventory source shape must use "
"literal tuple assignments"
)
source_nodes.append(source_node)
return (source_nodes[0], source_nodes[1])
def test_training_m75_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_self_lock(
self,
) -> None:
guard_name = (
"test_training_m75_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_self_lock"
)
m74_guard_name = (
"test_training_m74_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_self_lock"
)
expected_fixture_diagnostics = (
("missing_assignment", "must have one assignment"),
("duplicate_top_level_assignment", "must have one assignment"),
("multiple_assignment_targets", "must use one simple assignment"),
(
"empty_tuple",
"must be a literal triplet tuple assignment",
),
(
"two_item_tuple",
"must be a literal triplet tuple assignment",
),
(
"four_item_tuple",
"must be a literal triplet tuple assignment",
),
("integer_literal_method_name", "must use literal method names"),
("none_literal_method_name", "must use literal method names"),
)
expected_allowed_diagnostic_snippets = (
"must have one assignment",
"must use one simple assignment",
"must be a literal triplet tuple assignment",
"must use literal method names",
)
module_source = Path(__file__).read_text(encoding="utf-8")
module_tree = ast.parse(module_source)
m74_methods = tuple(
node
for node in ast.walk(module_tree)
if isinstance(node, ast.FunctionDef) and node.name == m74_guard_name
)
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
self.assertEqual(len(m74_methods), 1)
m74_method = m74_methods[0]
fixture_source, snippet_source = (
self._release_index_m74_diagnostic_fixture_inventory_source_nodes(
m74_method
)
)
self.assertIsInstance(fixture_source, ast.Tuple)
self.assertIsInstance(snippet_source, ast.Tuple)
fixture_diagnostics = ast.literal_eval(fixture_source)
diagnostic_snippets = ast.literal_eval(snippet_source)
self.assertEqual(fixture_diagnostics, expected_fixture_diagnostics)
self.assertEqual(diagnostic_snippets, expected_allowed_diagnostic_snippets)
self.assertNotEqual(fixture_diagnostics, tuple(sorted(fixture_diagnostics)))
self.assertNotEqual(diagnostic_snippets, tuple(sorted(diagnostic_snippets)))
self.assertEqual(len(fixture_source.elts), 8)
self.assertTrue(
all(
isinstance(fixture_tuple, ast.Tuple) and len(fixture_tuple.elts) == 2
for fixture_tuple in fixture_source.elts
)
)
fixture_literal_nodes = tuple(
fixture_literal
for fixture_tuple in fixture_source.elts
for fixture_literal in fixture_tuple.elts
)
self.assertTrue(
all(
isinstance(fixture_literal, ast.Constant)
and isinstance(fixture_literal.value, str)
for fixture_literal in fixture_literal_nodes
)
)
self.assertEqual(len(snippet_source.elts), 4)
self.assertTrue(
all(
isinstance(snippet_literal, ast.Constant)
and isinstance(snippet_literal.value, str)
and bool(snippet_literal.value)
for snippet_literal in snippet_source.elts
)
)
def test_training_m76_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_rejects_dynamic_sources(
self,
) -> None:
guard_name = (
"test_training_m76_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_rejects_dynamic_sources"
)
fixture_pair = "('missing_assignment', 'must have one assignment')"
snippet = "'must have one assignment'"
valid_fixture_source = f"({fixture_pair},)"
valid_snippet_source = f"({snippet},)"
def synthetic_m74_method(
fixture_source: str,
snippet_source: str,
prefix: str = "",
) -> ast.FunctionDef:
module_tree = ast.parse(
"def test_training_m74_synthetic_guard(self):\n"
f"{prefix}"
f" expected_fixture_diagnostics = {fixture_source}\n"
f" allowed_diagnostic_snippets = {snippet_source}\n"
)
self.assertEqual(len(module_tree.body), 1)
method = module_tree.body[0]
self.assertIsInstance(method, ast.FunctionDef)
return method
invalid_sources = {
"fixture_list_literal": (
f"[{fixture_pair}]",
valid_snippet_source,
"",
"List",
),
"fixture_name_alias": (
"fixture_diagnostics",
valid_snippet_source,
f" fixture_diagnostics = ({fixture_pair},)\n",
"Name",
),
"fixture_tuple_call": (
f"tuple(({fixture_pair},))",
valid_snippet_source,
"",
"Call",
),
"fixture_dict_literal": (
"{'missing_assignment': 'must have one assignment'}",
valid_snippet_source,
"",
"Dict",
),
"fixture_set_literal": (
f"{{{fixture_pair}}}",
valid_snippet_source,
"",
"Set",
),
"fixture_list_comprehension": (
f"[diagnostic for diagnostic in ({fixture_pair},)]",
valid_snippet_source,
"",
"ListComp",
),
"snippet_generator_expression": (
valid_fixture_source,
f"(snippet for snippet in ({snippet},))",
"",
"GeneratorExp",
),
"snippet_starred_tuple": (
valid_fixture_source,
f"(*({snippet},),)",
"",
"Starred",
),
}
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
for fixture_name, (
fixture_source,
snippet_source,
prefix,
node_type,
) in invalid_sources.items():
with self.subTest(fixture_name=fixture_name):
with self.assertRaisesRegex(
AssertionError,
re.escape(f"dynamic source node {node_type}"),
):
self._release_index_m74_diagnostic_fixture_inventory_source_nodes(
synthetic_m74_method(fixture_source, snippet_source, prefix)
)
def test_training_m77_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_edge_diagnostics_are_locked(
self,
) -> None:
guard_name = (
"test_training_m77_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_edge_diagnostics_are_locked"
)
fixture_pair = "('missing_assignment', 'must have one assignment')"
snippet = "'must have one assignment'"
valid_fixture_source = f"({fixture_pair},)"
valid_snippet_source = f"({snippet},)"
expected_assignment = (
f" expected_fixture_diagnostics = {valid_fixture_source}\n"
)
allowed_assignment = (
f" allowed_diagnostic_snippets = {valid_snippet_source}\n"
)
def synthetic_m74_method(source_body: str) -> ast.FunctionDef:
module_tree = ast.parse(
"def test_training_m74_synthetic_guard(self):\n"
f"{source_body}"
)
self.assertEqual(len(module_tree.body), 1)
method = module_tree.body[0]
self.assertIsInstance(method, ast.FunctionDef)
return method
invalid_sources = {
"missing_expected_assignment": (
allowed_assignment,
"must have one expected_fixture_diagnostics assignment",
),
"duplicate_expected_assignment": (
f"{expected_assignment}{expected_assignment}{allowed_assignment}",
"must have one expected_fixture_diagnostics assignment",
),
"annotated_expected_assignment": (
f" expected_fixture_diagnostics: tuple = {valid_fixture_source}\n"
f"{allowed_assignment}",
"must use one simple expected_fixture_diagnostics assignment",
),
"augmented_expected_assignment": (
f" expected_fixture_diagnostics += {valid_fixture_source}\n"
f"{allowed_assignment}",
"must use one simple expected_fixture_diagnostics assignment",
),
"missing_allowed_assignment": (
expected_assignment,
"must have one allowed_diagnostic_snippets assignment",
),
"duplicate_allowed_assignment": (
f"{expected_assignment}{allowed_assignment}{allowed_assignment}",
"must have one allowed_diagnostic_snippets assignment",
),
"annotated_allowed_assignment": (
f"{expected_assignment}"
f" allowed_diagnostic_snippets: tuple = {valid_snippet_source}\n",
"must use one simple allowed_diagnostic_snippets assignment",
),
"augmented_allowed_assignment": (
f"{expected_assignment}"
f" allowed_diagnostic_snippets += {valid_snippet_source}\n",
"must use one simple allowed_diagnostic_snippets assignment",
),
"fixture_scalar_string": (
f" expected_fixture_diagnostics = {snippet}\n"
f"{allowed_assignment}",
"literal tuple assignments",
),
"snippet_scalar_string": (
f"{expected_assignment}"
f" allowed_diagnostic_snippets = {snippet}\n",
"literal tuple assignments",
),
"fixture_empty_tuple": (
f" expected_fixture_diagnostics = ()\n{allowed_assignment}",
"literal tuple assignments",
),
"snippet_empty_tuple": (
f"{expected_assignment} allowed_diagnostic_snippets = ()\n",
"literal tuple assignments",
),
"fixture_empty_list": (
f" expected_fixture_diagnostics = []\n{allowed_assignment}",
"dynamic source node List",
),
"snippet_empty_list": (
f"{expected_assignment} allowed_diagnostic_snippets = []\n",
"dynamic source node List",
),
}
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
for fixture_name, (source_body, error_snippet) in invalid_sources.items():
with self.subTest(fixture_name=fixture_name):
with self.assertRaisesRegex(
AssertionError,
re.escape(error_snippet),
):
self._release_index_m74_diagnostic_fixture_inventory_source_nodes(
synthetic_m74_method(source_body)
)
def test_training_m78_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_accepts_ordered_literal_sources(
self,
) -> None:
guard_name = (
"test_training_m78_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_accepts_ordered_literal_sources"
)
expected_fixture_diagnostics = (
("zeta_fixture_gap", "zeta diagnostic stays literal"),
("alpha_fixture_gap", "alpha diagnostic stays literal"),
("mango_fixture_gap", "mango diagnostic stays literal"),
)
expected_allowed_diagnostic_snippets = (
"zeta diagnostic stays literal",
"alpha diagnostic stays literal",
"mango diagnostic stays literal",
)
disallowed_source_node_types = (
ast.BinOp,
ast.Call,
ast.Dict,
ast.DictComp,
ast.GeneratorExp,
ast.List,
ast.ListComp,
ast.Name,
ast.Set,
ast.SetComp,
ast.Starred,
)
def synthetic_m74_method() -> ast.FunctionDef:
module_tree = ast.parse(
"def test_training_m74_synthetic_guard(self):\n"
" expected_fixture_diagnostics = (\n"
" ('zeta_fixture_gap', 'zeta diagnostic stays literal'),\n"
" ('alpha_fixture_gap', 'alpha diagnostic stays literal'),\n"
" ('mango_fixture_gap', 'mango diagnostic stays literal'),\n"
" )\n"
" allowed_diagnostic_snippets = (\n"
" 'zeta diagnostic stays literal',\n"
" 'alpha diagnostic stays literal',\n"
" 'mango diagnostic stays literal',\n"
" )\n"
)
self.assertEqual(len(module_tree.body), 1)
method = module_tree.body[0]
self.assertIsInstance(method, ast.FunctionDef)
return method
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
fixture_source, snippet_source = (
self._release_index_m74_diagnostic_fixture_inventory_source_nodes(
synthetic_m74_method()
)
)
self.assertIsInstance(fixture_source, ast.Tuple)
self.assertIsInstance(snippet_source, ast.Tuple)
fixture_diagnostics = ast.literal_eval(fixture_source)
diagnostic_snippets = ast.literal_eval(snippet_source)
self.assertEqual(fixture_diagnostics, expected_fixture_diagnostics)
self.assertEqual(diagnostic_snippets, expected_allowed_diagnostic_snippets)
self.assertNotEqual(
expected_fixture_diagnostics,
tuple(sorted(expected_fixture_diagnostics)),
)
self.assertNotEqual(
expected_allowed_diagnostic_snippets,
tuple(sorted(expected_allowed_diagnostic_snippets)),
)
self.assertTrue(
all(
isinstance(fixture_tuple, ast.Tuple) and len(fixture_tuple.elts) == 2
for fixture_tuple in fixture_source.elts
)
)
fixture_literal_nodes = tuple(
fixture_literal
for fixture_tuple in fixture_source.elts
for fixture_literal in fixture_tuple.elts
)
self.assertTrue(
all(
isinstance(fixture_literal, ast.Constant)
and isinstance(fixture_literal.value, str)
for fixture_literal in fixture_literal_nodes
)
)
self.assertTrue(
all(
isinstance(snippet_literal, ast.Constant)
and isinstance(snippet_literal.value, str)
for snippet_literal in snippet_source.elts
)
)
self.assertFalse(
any(
isinstance(node, disallowed_source_node_types)
for node in (
*ast.walk(fixture_source),
*ast.walk(snippet_source),
)
)
)
def test_training_m79_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_self_lock(
self,
) -> None:
guard_name = (
"test_training_m79_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_self_lock"
)
diagnostic_fixture_inventory_guard_cluster = (
TRAINING_M41_RELEASE_INDEX_DIAGNOSTIC_FIXTURE_INVENTORY_GUARD_CLUSTER
)
module_source = Path(__file__).read_text(encoding="utf-8")
module_tree = ast.parse(module_source)
test_case_name = f"{type(self).__module__}.{type(self).__qualname__}"
def local_assignment_value(method_name: str, local_name: str) -> ast.AST:
methods = tuple(
node
for node in ast.walk(module_tree)
if isinstance(node, ast.FunctionDef) and node.name == method_name
)
self.assertEqual(len(methods), 1)
assignments = tuple(
node.value
for node in ast.walk(methods[0])
if (
isinstance(node, ast.Assign)
and len(node.targets) == 1
and isinstance(node.targets[0], ast.Name)
and node.targets[0].id == local_name
)
)
self.assertEqual(len(assignments), 1)
return assignments[0]
role_mapping = ast.literal_eval(
local_assignment_value(
"test_training_m41_release_index_guard_inventory_is_current",
"required_guard_tests_by_role",
)
)
expected_inventory = ast.literal_eval(
local_assignment_value(
"test_training_m52_release_index_guard_inventory_order_and_uniqueness_self_lock",
"expected_inventory",
)
)
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
self.assertEqual(len(diagnostic_fixture_inventory_guard_cluster), 5)
for method_name in diagnostic_fixture_inventory_guard_cluster:
with self.subTest(method_name=method_name):
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.count(
method_name
),
1,
)
loader = unittest.TestLoader()
suite = loader.loadTestsFromName(f"{test_case_name}.{method_name}")
self.assertEqual(loader.errors, [])
self.assertEqual(suite.countTestCases(), 1)
cluster_start = TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
diagnostic_fixture_inventory_guard_cluster[0]
)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY[
cluster_start : cluster_start
+ len(diagnostic_fixture_inventory_guard_cluster)
],
diagnostic_fixture_inventory_guard_cluster,
)
self.assertEqual(
tuple(
method_name
for method_name in role_mapping.values()
if method_name in diagnostic_fixture_inventory_guard_cluster
),
diagnostic_fixture_inventory_guard_cluster,
)
self.assertEqual(
tuple(
method_name
for method_name in expected_inventory
if method_name in diagnostic_fixture_inventory_guard_cluster
),
diagnostic_fixture_inventory_guard_cluster,
)
def test_training_m80_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_negative_fixture_self_lock(
self,
) -> None:
guard_name = (
"test_training_m80_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_negative_fixture_self_lock"
)
diagnostic_fixture_inventory_guard_cluster = (
TRAINING_M41_RELEASE_INDEX_DIAGNOSTIC_FIXTURE_INVENTORY_GUARD_CLUSTER
)
base_inventory = TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY
cluster_start = base_inventory.index(diagnostic_fixture_inventory_guard_cluster[0])
separator_method = base_inventory[0]
def validate_diagnostic_fixture_inventory_guard_cluster(
inventory: tuple[str, ...],
) -> None:
missing_methods = tuple(
method_name
for method_name in diagnostic_fixture_inventory_guard_cluster
if method_name not in inventory
)
if missing_methods:
raise AssertionError(
"missing diagnostic fixture inventory guard cluster method "
f"{missing_methods[0]}"
)
duplicate_methods = tuple(
method_name
for method_name in diagnostic_fixture_inventory_guard_cluster
if inventory.count(method_name) != 1
)
if duplicate_methods:
raise AssertionError(
"duplicate diagnostic fixture inventory guard cluster method "
f"{duplicate_methods[0]}"
)
cluster_positions = tuple(
inventory.index(method_name)
for method_name in diagnostic_fixture_inventory_guard_cluster
)
ordered_positions = tuple(sorted(cluster_positions))
expected_positions = tuple(
range(ordered_positions[0], ordered_positions[0] + len(ordered_positions))
)
if ordered_positions != expected_positions:
raise AssertionError(
"contiguous diagnostic fixture inventory guard cluster positions "
f"{ordered_positions}"
)
ordered_cluster = inventory[
ordered_positions[0] : ordered_positions[0]
+ len(diagnostic_fixture_inventory_guard_cluster)
]
if ordered_cluster != diagnostic_fixture_inventory_guard_cluster:
raise AssertionError(
"order diagnostic fixture inventory guard cluster mismatch "
f"{ordered_cluster}"
)
negative_inventories = {
"missing": (
tuple(
method_name
for method_name in base_inventory
if method_name != diagnostic_fixture_inventory_guard_cluster[2]
),
"missing",
),
"duplicate": (
(*base_inventory, diagnostic_fixture_inventory_guard_cluster[1]),
"duplicate",
),
"contiguous": (
(
*base_inventory[: cluster_start + 2],
separator_method,
*base_inventory[cluster_start + 2 :],
),
"contiguous",
),
"order": (
(
*base_inventory[:cluster_start],
diagnostic_fixture_inventory_guard_cluster[1],
diagnostic_fixture_inventory_guard_cluster[0],
*diagnostic_fixture_inventory_guard_cluster[2:],
*base_inventory[
cluster_start
+ len(diagnostic_fixture_inventory_guard_cluster) :
],
),
"order",
),
}
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
validate_diagnostic_fixture_inventory_guard_cluster(base_inventory)
for fixture_name, (
synthetic_inventory,
diagnostic_snippet,
) in negative_inventories.items():
with self.subTest(fixture_name=fixture_name):
with self.assertRaisesRegex(
AssertionError,
re.escape(diagnostic_snippet),
):
validate_diagnostic_fixture_inventory_guard_cluster(
synthetic_inventory
)
@staticmethod
def _release_index_diagnostic_fixture_inventory_guard_cluster_from_source(
module_source: str,
) -> tuple[str, ...]:
constant_name = (
"TRAINING_M41_RELEASE_INDEX_DIAGNOSTIC_FIXTURE_INVENTORY_GUARD_CLUSTER"
)
disallowed_source_node_types = (
ast.Call,
ast.Dict,
ast.GeneratorExp,
ast.List,
ast.ListComp,
ast.Name,
ast.Set,
ast.Starred,
)
module_tree = ast.parse(module_source)
def assigns_constant(node: ast.AST) -> bool:
if isinstance(node, ast.Assign):
targets = node.targets
elif isinstance(node, (ast.AnnAssign, ast.AugAssign)):
targets = (node.target,)
else:
return False
return any(
isinstance(target, ast.Name) and target.id == constant_name
for target in targets
)
constant_assignments = tuple(
node for node in module_tree.body if assigns_constant(node)
)
if len(constant_assignments) != 1:
raise AssertionError(
"diagnostic fixture inventory guard cluster must have one assignment"
)
constant_assignment = constant_assignments[0]
if (
not isinstance(constant_assignment, ast.Assign)
or len(constant_assignment.targets) != 1
or not isinstance(constant_assignment.targets[0], ast.Name)
):
raise AssertionError(
"diagnostic fixture inventory guard cluster must be a simple assignment"
)
constant_source = constant_assignment.value
dynamic_source_node = next(
(
node
for node in ast.walk(constant_source)
if isinstance(node, disallowed_source_node_types)
),
None,
)
if dynamic_source_node is not None:
dynamic_node = type(dynamic_source_node).__name__
raise AssertionError(
"diagnostic fixture inventory guard cluster uses dynamic source node "
f"{dynamic_node}"
)
if not isinstance(constant_source, ast.Tuple):
raise AssertionError(
"diagnostic fixture inventory guard cluster must be a literal tuple assignment"
)
if not constant_source.elts or not all(
isinstance(method_node, ast.Constant)
and isinstance(method_node.value, str)
for method_node in constant_source.elts
):
raise AssertionError(
"diagnostic fixture inventory guard cluster must use literal method names"
)
try:
method_names = ast.literal_eval(constant_source)
except (SyntaxError, ValueError) as exc:
raise AssertionError(
"diagnostic fixture inventory guard cluster must use literal method names"
) from exc
if not all(isinstance(method_name, str) for method_name in method_names):
raise AssertionError(
"diagnostic fixture inventory guard cluster must use literal method names"
)
return method_names
def test_training_m81_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_self_lock(
self,
) -> None:
guard_name = (
"test_training_m81_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_self_lock"
)
expected_cluster = (
"test_training_m74_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_self_lock",
"test_training_m75_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_self_lock",
"test_training_m76_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_rejects_dynamic_sources",
"test_training_m77_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_edge_diagnostics_are_locked",
"test_training_m78_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_source_shape_accepts_ordered_literal_sources",
)
module_source = Path(__file__).read_text(encoding="utf-8")
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
constant_cluster = (
self._release_index_diagnostic_fixture_inventory_guard_cluster_from_source(
module_source
)
)
self.assertEqual(constant_cluster, expected_cluster)
self.assertEqual(len(constant_cluster), 5)
self.assertEqual(len(constant_cluster), len(set(constant_cluster)))
for method_name in constant_cluster:
with self.subTest(method_name=method_name):
self.assertIn(
method_name,
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY,
)
def test_training_m82_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_rejects_dynamic_sources(
self,
) -> None:
constant_name = (
"TRAINING_M41_RELEASE_INDEX_DIAGNOSTIC_FIXTURE_INVENTORY_GUARD_CLUSTER"
)
guard_name = (
"test_training_m82_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_rejects_dynamic_sources"
)
first_method = "literal_method_alpha"
second_method = "literal_method_beta"
invalid_sources = {
"list_literal": (
f"{constant_name} = [{first_method!r}, {second_method!r}]",
"dynamic source node List",
),
"name_reference": (
f"fixture_guard_methods = ({first_method!r}, {second_method!r})\n"
f"{constant_name} = fixture_guard_methods",
"dynamic source node Name",
),
"tuple_call": (
f"{constant_name} = tuple(({first_method!r}, {second_method!r}))",
"dynamic source node Call",
),
"sorted_call": (
f"{constant_name} = sorted(({first_method!r}, {second_method!r}))",
"dynamic source node Call",
),
"set_literal": (
f"{constant_name} = {{{first_method!r}, {second_method!r}}}",
"dynamic source node Set",
),
"dict_literal": (
f"{constant_name} = {{{first_method!r}: {second_method!r}}}",
"dynamic source node Dict",
),
"list_comprehension": (
f"{constant_name} = [method for method in ({first_method!r}, {second_method!r})]",
"dynamic source node ListComp",
),
"generator_expression": (
f"{constant_name} = (method for method in ({first_method!r}, {second_method!r}))",
"dynamic source node GeneratorExp",
),
"starred_tuple": (
f"fixture_guard_methods = ({second_method!r},)\n"
f"{constant_name} = ({first_method!r}, *fixture_guard_methods)",
"dynamic source node Starred",
),
}
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
for fixture_name, (source, error_snippet) in invalid_sources.items():
with self.subTest(fixture_name=fixture_name):
with self.assertRaisesRegex(AssertionError, re.escape(error_snippet)):
self._release_index_diagnostic_fixture_inventory_guard_cluster_from_source(
source
)
def test_training_m83_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_edge_diagnostics_are_locked(
self,
) -> None:
constant_name = (
"TRAINING_M41_RELEASE_INDEX_DIAGNOSTIC_FIXTURE_INVENTORY_GUARD_CLUSTER"
)
guard_name = (
"test_training_m83_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_edge_diagnostics_are_locked"
)
first_method = "literal_method_alpha"
second_method = "literal_method_beta"
invalid_sources = {
"missing_target_assignment": (
"UNRELATED_FIXTURE_GUARD_CLUSTER = ()",
"must have one assignment",
),
"duplicate_top_level_assignments": (
f"{constant_name} = ({first_method!r},)\n"
f"{constant_name} = ({second_method!r},)",
"must have one assignment",
),
"annotated_assignment": (
f"{constant_name}: tuple[str, ...] = ({first_method!r},)",
"must be a simple assignment",
),
"augmented_assignment": (
f"{constant_name} += ({first_method!r},)",
"must be a simple assignment",
),
"empty_tuple_assignment": (
f"{constant_name} = ()",
"must use literal method names",
),
"integer_literal_method_name": (
f"{constant_name} = ({first_method!r}, 123)",
"must use literal method names",
),
"none_literal_method_name": (
f"{constant_name} = ({first_method!r}, None)",
"must use literal method names",
),
"scalar_string_assignment": (
f"{constant_name} = {first_method!r}",
"must be a literal tuple assignment",
),
}
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
for fixture_name, (source, error_snippet) in invalid_sources.items():
with self.subTest(fixture_name=fixture_name):
with self.assertRaisesRegex(AssertionError, re.escape(error_snippet)):
self._release_index_diagnostic_fixture_inventory_guard_cluster_from_source(
source
)
def test_training_m84_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_inventory_self_lock(
self,
) -> None:
guard_name = (
"test_training_m84_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_inventory_self_lock"
)
expected_governance_methods = (
"test_training_m79_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_self_lock",
"test_training_m80_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_negative_fixture_self_lock",
"test_training_m81_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_self_lock",
"test_training_m82_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_rejects_dynamic_sources",
"test_training_m83_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_edge_diagnostics_are_locked",
)
governance_methods = (
TRAINING_M41_RELEASE_INDEX_DIAGNOSTIC_FIXTURE_INVENTORY_GUARD_CLUSTER_GOVERNANCE_METHODS
)
module_source = Path(__file__).read_text(encoding="utf-8")
module_tree = ast.parse(module_source)
test_case_name = f"{type(self).__module__}.{type(self).__qualname__}"
def local_assignment_value(method_name: str, local_name: str) -> ast.AST:
methods = tuple(
node
for node in ast.walk(module_tree)
if isinstance(node, ast.FunctionDef) and node.name == method_name
)
self.assertEqual(len(methods), 1)
assignments = tuple(
node.value
for node in ast.walk(methods[0])
if (
isinstance(node, ast.Assign)
and len(node.targets) == 1
and isinstance(node.targets[0], ast.Name)
and node.targets[0].id == local_name
)
)
self.assertEqual(len(assignments), 1)
return assignments[0]
role_mapping = ast.literal_eval(
local_assignment_value(
"test_training_m41_release_index_guard_inventory_is_current",
"required_guard_tests_by_role",
)
)
role_methods = tuple(role_mapping.values())
expected_inventory = ast.literal_eval(
local_assignment_value(
"test_training_m52_release_index_guard_inventory_order_and_uniqueness_self_lock",
"expected_inventory",
)
)
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
self.assertIn(guard_name, role_methods)
self.assertIn(guard_name, expected_inventory)
self.assertEqual(governance_methods, expected_governance_methods)
self.assertEqual(len(governance_methods), len(set(governance_methods)))
for method_name in governance_methods:
with self.subTest(method_name=method_name):
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.count(
method_name
),
1,
)
self.assertEqual(role_methods.count(method_name), 1)
self.assertEqual(expected_inventory.count(method_name), 1)
loader = unittest.TestLoader()
suite = loader.loadTestsFromName(f"{test_case_name}.{method_name}")
self.assertEqual(loader.errors, [])
self.assertEqual(suite.countTestCases(), 1)
governance_start = TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
governance_methods[0]
)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY[
governance_start : governance_start + len(governance_methods)
],
governance_methods,
)
self.assertEqual(
tuple(
method_name
for method_name in role_methods
if method_name in governance_methods
),
governance_methods,
)
self.assertEqual(
tuple(
method_name
for method_name in expected_inventory
if method_name in governance_methods
),
governance_methods,
)
def test_training_m85_release_index_public_docs_acceptance_inventory_alignment_self_lock(
self,
) -> None:
guard_name = (
"test_training_m85_release_index_public_docs_acceptance_inventory_alignment_self_lock"
)
recent_closure_methods = (
"test_training_m79_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_self_lock",
"test_training_m80_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_negative_fixture_self_lock",
"test_training_m81_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_self_lock",
"test_training_m82_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_rejects_dynamic_sources",
"test_training_m83_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_edge_diagnostics_are_locked",
"test_training_m84_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_inventory_self_lock",
)
grouped_inventory = TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY
inventory_by_category = dict(grouped_inventory)
flattened_required_snippets = tuple(
snippet
for _, snippets in grouped_inventory
for snippet in snippets
)
text_by_doc = {
path: path.read_text(encoding="utf-8")
for path in TRAINING_M41_RELEASE_INDEX_DOCS
}
missing_by_doc = _release_index_missing_required_snippets_by_doc(text_by_doc)
module_source = Path(__file__).read_text(encoding="utf-8")
module_tree = ast.parse(module_source)
def local_assignment_value(method_name: str, local_name: str) -> ast.AST:
methods = tuple(
node
for node in ast.walk(module_tree)
if isinstance(node, ast.FunctionDef) and node.name == method_name
)
self.assertEqual(len(methods), 1)
assignments = tuple(
node.value
for node in ast.walk(methods[0])
if (
isinstance(node, ast.Assign)
and len(node.targets) == 1
and isinstance(node.targets[0], ast.Name)
and node.targets[0].id == local_name
)
)
self.assertEqual(len(assignments), 1)
return assignments[0]
role_mapping = ast.literal_eval(
local_assignment_value(
"test_training_m41_release_index_guard_inventory_is_current",
"required_guard_tests_by_role",
)
)
role_methods = tuple(role_mapping.values())
expected_inventory = ast.literal_eval(
local_assignment_value(
"test_training_m52_release_index_guard_inventory_order_and_uniqueness_self_lock",
"expected_inventory",
)
)
self.assertEqual(tuple(text_by_doc), TRAINING_M41_RELEASE_INDEX_DOCS)
self.assertEqual(tuple(missing_by_doc), TRAINING_M41_RELEASE_INDEX_DOCS)
for path in TRAINING_M41_RELEASE_INDEX_DOCS:
with self.subTest(path=path.name):
self.assertEqual(missing_by_doc[path], ())
self.assertEqual(
inventory_by_category["acceptance_offline_validation"],
TRAINING_ACCEPTANCE_VALIDATION_DOC_SNIPPETS,
)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_DOC_SNIPPETS,
flattened_required_snippets,
)
for category, snippets in grouped_inventory:
with self.subTest(category=category):
self.assertTrue(snippets)
self.assertEqual(
tuple(category for category, _ in grouped_inventory),
tuple(inventory_by_category),
)
recent_start = TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
recent_closure_methods[0]
)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY[
recent_start : recent_start + len(recent_closure_methods)
],
recent_closure_methods,
)
for method_name in recent_closure_methods:
with self.subTest(method_name=method_name):
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.count(
method_name
),
1,
)
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
self.assertIn(guard_name, role_methods)
self.assertIn(guard_name, expected_inventory)
def test_training_m86_release_index_final_closure_delivery_index_self_lock(
self,
) -> None:
guard_name = "test_training_m86_release_index_final_closure_delivery_index_self_lock"
closure_methods = (
"test_training_m79_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_self_lock",
"test_training_m80_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_negative_fixture_self_lock",
"test_training_m81_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_self_lock",
"test_training_m82_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_rejects_dynamic_sources",
"test_training_m83_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_constant_source_shape_edge_diagnostics_are_locked",
"test_training_m84_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_inventory_self_lock",
"test_training_m85_release_index_public_docs_acceptance_inventory_alignment_self_lock",
)
module_source = Path(__file__).read_text(encoding="utf-8")
module_tree = ast.parse(module_source)
test_case_name = f"{type(self).__module__}.{type(self).__qualname__}"
def local_assignment_value(method_name: str, local_name: str) -> ast.AST:
methods = tuple(
node
for node in ast.walk(module_tree)
if isinstance(node, ast.FunctionDef) and node.name == method_name
)
self.assertEqual(len(methods), 1)
assignments = tuple(
node.value
for node in ast.walk(methods[0])
if (
isinstance(node, ast.Assign)
and len(node.targets) == 1
and isinstance(node.targets[0], ast.Name)
and node.targets[0].id == local_name
)
)
self.assertEqual(len(assignments), 1)
return assignments[0]
role_mapping = ast.literal_eval(
local_assignment_value(
"test_training_m41_release_index_guard_inventory_is_current",
"required_guard_tests_by_role",
)
)
role_methods = tuple(role_mapping.values())
expected_inventory = ast.literal_eval(
local_assignment_value(
"test_training_m52_release_index_guard_inventory_order_and_uniqueness_self_lock",
"expected_inventory",
)
)
m84_governance_methods = ast.literal_eval(
local_assignment_value(
"test_training_m84_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_inventory_self_lock",
"expected_governance_methods",
)
)
delivery_methods = (*closure_methods, guard_name)
closure_start = TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
closure_methods[0]
)
m79_m83_methods = closure_methods[:5]
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY[
closure_start : closure_start + len(closure_methods)
],
closure_methods,
)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY[
closure_start : closure_start + len(delivery_methods)
],
delivery_methods,
)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_DIAGNOSTIC_FIXTURE_INVENTORY_GUARD_CLUSTER_GOVERNANCE_METHODS,
m79_m83_methods,
)
self.assertEqual(m84_governance_methods, m79_m83_methods)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
"test_training_m85_release_index_public_docs_acceptance_inventory_alignment_self_lock"
),
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
"test_training_m84_release_index_source_shape_fixture_guard_methods_constant_exactness_bridge_triplet_diagnostic_fixture_inventory_guard_cluster_inventory_self_lock"
)
+ 1,
)
for method_name in closure_methods:
with self.subTest(method_name=method_name):
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.count(
method_name
),
1,
)
self.assertEqual(role_methods.count(method_name), 1)
self.assertEqual(expected_inventory.count(method_name), 1)
loader = unittest.TestLoader()
suite = loader.loadTestsFromName(f"{test_case_name}.{method_name}")
self.assertEqual(loader.errors, [])
self.assertEqual(suite.countTestCases(), 1)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.count(guard_name),
1,
)
self.assertEqual(role_methods.count(guard_name), 1)
self.assertEqual(expected_inventory.count(guard_name), 1)
self.assertEqual(CURRENT_TRAINING_DOC_MATURITY_MARKER, "M1-M40")
self.assertEqual(CURRENT_TRAINING_DOC_MATURITY_SPAN, "through M40")
self.assertEqual(
CURRENT_TRAINING_DOC_MATURITY_PHRASE,
"current product maturity through M40",
)
for path in TRAINING_M41_RELEASE_INDEX_DOCS:
text = path.read_text(encoding="utf-8")
with self.subTest(path=path.name):
self.assertIn(CURRENT_TRAINING_DOC_MATURITY_MARKER, text)
self.assertIn(CURRENT_TRAINING_DOC_MATURITY_SPAN, text)
def test_training_m87_release_index_final_closure_delivery_index_guard_self_lock(
self,
) -> None:
guard_name = (
"test_training_m87_release_index_final_closure_delivery_index_guard_self_lock"
)
final_closure_guard_name = (
"test_training_m86_release_index_final_closure_delivery_index_self_lock"
)
module_source = Path(__file__).read_text(encoding="utf-8")
module_tree = ast.parse(module_source)
test_case_name = f"{type(self).__module__}.{type(self).__qualname__}"
functions_by_name = {
node.name: ast.get_source_segment(module_source, node) or ""
for node in ast.walk(module_tree)
if isinstance(node, ast.FunctionDef)
}
def local_assignment_value(method_name: str, local_name: str) -> ast.AST:
methods = tuple(
node
for node in ast.walk(module_tree)
if isinstance(node, ast.FunctionDef) and node.name == method_name
)
self.assertEqual(len(methods), 1)
assignments = tuple(
node.value
for node in ast.walk(methods[0])
if (
isinstance(node, ast.Assign)
and len(node.targets) == 1
and isinstance(node.targets[0], ast.Name)
and node.targets[0].id == local_name
)
)
self.assertEqual(len(assignments), 1)
return assignments[0]
role_mapping = ast.literal_eval(
local_assignment_value(
"test_training_m41_release_index_guard_inventory_is_current",
"required_guard_tests_by_role",
)
)
role_methods = tuple(role_mapping.values())
expected_inventory = ast.literal_eval(
local_assignment_value(
"test_training_m52_release_index_guard_inventory_order_and_uniqueness_self_lock",
"expected_inventory",
)
)
closure_methods = ast.literal_eval(
local_assignment_value(final_closure_guard_name, "closure_methods")
)
delivery_methods = (*closure_methods, final_closure_guard_name)
delivery_start = TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
delivery_methods[0]
)
self.assertIn(final_closure_guard_name, functions_by_name)
for source_reference in (
"delivery_methods = (*closure_methods, guard_name)",
"closure_start : closure_start + len(delivery_methods)",
"CURRENT_TRAINING_DOC_MATURITY_MARKER, \"M1-M40\"",
"CURRENT_TRAINING_DOC_MATURITY_SPAN, \"through M40\"",
):
with self.subTest(source_reference=source_reference):
self.assertIn(
source_reference,
functions_by_name[final_closure_guard_name],
)
self.assertEqual(delivery_methods[-1], final_closure_guard_name)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY[
delivery_start : delivery_start + len(delivery_methods)
],
delivery_methods,
)
for method_name in delivery_methods:
with self.subTest(method_name=method_name):
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.count(
method_name
),
1,
)
self.assertEqual(role_methods.count(method_name), 1)
self.assertEqual(expected_inventory.count(method_name), 1)
loader = unittest.TestLoader()
suite = loader.loadTestsFromName(f"{test_case_name}.{method_name}")
self.assertEqual(loader.errors, [])
self.assertEqual(suite.countTestCases(), 1)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.count(guard_name),
1,
)
self.assertEqual(role_methods.count(guard_name), 1)
self.assertEqual(expected_inventory.count(guard_name), 1)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(guard_name),
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
final_closure_guard_name
)
+ 1,
)
self.assertEqual(
role_mapping["release_index_final_closure_delivery_guard_self_lock"],
guard_name,
)
def test_training_m88_release_index_final_closure_delivery_guard_source_self_lock(
self,
) -> None:
guard_name = (
"test_training_m88_release_index_final_closure_delivery_guard_source_self_lock"
)
guarded_method_name = (
"test_training_m87_release_index_final_closure_delivery_index_guard_self_lock"
)
final_closure_guard_name = (
"test_training_m86_release_index_final_closure_delivery_index_self_lock"
)
module_source = Path(__file__).read_text(encoding="utf-8")
module_tree = ast.parse(module_source)
test_case_name = f"{type(self).__module__}.{type(self).__qualname__}"
functions_by_name = {
node.name: node
for node in ast.walk(module_tree)
if isinstance(node, ast.FunctionDef)
}
def local_assignment_node(method_name: str, local_name: str) -> ast.AST:
self.assertIn(method_name, functions_by_name)
assignments = tuple(
node.value
for node in ast.walk(functions_by_name[method_name])
if (
isinstance(node, ast.Assign)
and len(node.targets) == 1
and isinstance(node.targets[0], ast.Name)
and node.targets[0].id == local_name
)
)
self.assertEqual(len(assignments), 1)
return assignments[0]
role_mapping = ast.literal_eval(
local_assignment_node(
"test_training_m41_release_index_guard_inventory_is_current",
"required_guard_tests_by_role",
)
)
role_methods = tuple(role_mapping.values())
expected_inventory = ast.literal_eval(
local_assignment_node(
"test_training_m52_release_index_guard_inventory_order_and_uniqueness_self_lock",
"expected_inventory",
)
)
closure_methods = ast.literal_eval(
local_assignment_node(final_closure_guard_name, "closure_methods")
)
delivery_methods = (
*closure_methods,
final_closure_guard_name,
guarded_method_name,
guard_name,
)
delivery_start = TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
delivery_methods[0]
)
guarded_delivery_node = local_assignment_node(
guarded_method_name,
"delivery_methods",
)
self.assertEqual(
ast.literal_eval(local_assignment_node(guarded_method_name, "guard_name")),
guarded_method_name,
)
self.assertEqual(
ast.literal_eval(
local_assignment_node(guarded_method_name, "final_closure_guard_name")
),
final_closure_guard_name,
)
self.assertIsInstance(guarded_delivery_node, ast.Tuple)
self.assertEqual(len(guarded_delivery_node.elts), 2)
self.assertIsInstance(guarded_delivery_node.elts[0], ast.Starred)
self.assertIsInstance(guarded_delivery_node.elts[0].value, ast.Name)
self.assertEqual(guarded_delivery_node.elts[0].value.id, "closure_methods")
self.assertIsInstance(guarded_delivery_node.elts[1], ast.Name)
self.assertEqual(
guarded_delivery_node.elts[1].id,
"final_closure_guard_name",
)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY[
delivery_start : delivery_start + len(delivery_methods)
],
delivery_methods,
)
for method_name in delivery_methods:
with self.subTest(method_name=method_name):
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.count(
method_name
),
1,
)
self.assertEqual(role_methods.count(method_name), 1)
self.assertEqual(expected_inventory.count(method_name), 1)
loader = unittest.TestLoader()
suite = loader.loadTestsFromName(f"{test_case_name}.{method_name}")
self.assertEqual(loader.errors, [])
self.assertEqual(suite.countTestCases(), 1)
self.assertEqual(
role_mapping.get("release_index_final_closure_delivery_guard_source_self_lock"),
guard_name,
)
self.assertEqual(CURRENT_TRAINING_DOC_MATURITY_MARKER, "M1-M40")
self.assertEqual(CURRENT_TRAINING_DOC_MATURITY_SPAN, "through M40")
def test_training_m89_release_index_final_closure_delivery_guard_source_chain_self_lock(
self,
) -> None:
guard_name = (
"test_training_m89_release_index_final_closure_delivery_guard_source_chain_self_lock"
)
final_closure_guard_name = (
"test_training_m86_release_index_final_closure_delivery_index_self_lock"
)
delivery_guard_name = (
"test_training_m87_release_index_final_closure_delivery_index_guard_self_lock"
)
source_guard_name = (
"test_training_m88_release_index_final_closure_delivery_guard_source_self_lock"
)
module_source = Path(__file__).read_text(encoding="utf-8")
module_tree = ast.parse(module_source)
test_case_name = f"{type(self).__module__}.{type(self).__qualname__}"
functions_by_name = {
node.name: node
for node in ast.walk(module_tree)
if isinstance(node, ast.FunctionDef)
}
def local_assignment_node(method_name: str, local_name: str) -> ast.AST:
self.assertIn(method_name, functions_by_name)
assignments = tuple(
node.value
for node in ast.walk(functions_by_name[method_name])
if (
isinstance(node, ast.Assign)
and len(node.targets) == 1
and isinstance(node.targets[0], ast.Name)
and node.targets[0].id == local_name
)
)
self.assertEqual(len(assignments), 1)
return assignments[0]
role_mapping = ast.literal_eval(
local_assignment_node(
"test_training_m41_release_index_guard_inventory_is_current",
"required_guard_tests_by_role",
)
)
role_methods = tuple(role_mapping.values())
expected_inventory = ast.literal_eval(
local_assignment_node(
"test_training_m52_release_index_guard_inventory_order_and_uniqueness_self_lock",
"expected_inventory",
)
)
closure_methods = ast.literal_eval(
local_assignment_node(final_closure_guard_name, "closure_methods")
)
source_delivery_node = local_assignment_node(
source_guard_name,
"delivery_methods",
)
delivery_chain = (
*closure_methods,
final_closure_guard_name,
delivery_guard_name,
source_guard_name,
guard_name,
)
chain_methods = delivery_chain[-4:]
chain_start = TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
delivery_chain[0]
)
self.assertEqual(
ast.literal_eval(
local_assignment_node(source_guard_name, "final_closure_guard_name")
),
final_closure_guard_name,
)
self.assertEqual(
ast.literal_eval(
local_assignment_node(source_guard_name, "guarded_method_name")
),
delivery_guard_name,
)
self.assertIsInstance(source_delivery_node, ast.Tuple)
self.assertEqual(len(source_delivery_node.elts), 4)
self.assertIsInstance(source_delivery_node.elts[0], ast.Starred)
self.assertIsInstance(source_delivery_node.elts[0].value, ast.Name)
self.assertEqual(source_delivery_node.elts[0].value.id, "closure_methods")
self.assertEqual(
tuple(
node.id
for node in source_delivery_node.elts[1:]
if isinstance(node, ast.Name)
),
("final_closure_guard_name", "guarded_method_name", "guard_name"),
)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY[
chain_start : chain_start + len(delivery_chain)
],
delivery_chain,
)
self.assertEqual(
tuple(
method_name
for method_name in role_methods
if method_name in chain_methods
),
chain_methods,
)
self.assertEqual(
tuple(
method_name
for method_name in expected_inventory
if method_name in chain_methods
),
chain_methods,
)
self.assertEqual(
role_mapping.get(
"release_index_final_closure_delivery_guard_source_chain_self_lock"
),
guard_name,
)
for method_name in chain_methods:
with self.subTest(method_name=method_name):
loader = unittest.TestLoader()
suite = loader.loadTestsFromName(f"{test_case_name}.{method_name}")
self.assertEqual(loader.errors, [])
self.assertEqual(suite.countTestCases(), 1)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.count(
method_name
),
1,
)
def test_training_m90_release_index_final_closure_delivery_guard_source_chain_source_shape_self_lock(
self,
) -> None:
guard_name = (
"test_training_m90_release_index_final_closure_delivery_guard_source_chain_source_shape_self_lock"
)
guarded_method_name = (
"test_training_m89_release_index_final_closure_delivery_guard_source_chain_self_lock"
)
expected_guard_chain_names = (
"test_training_m86_release_index_final_closure_delivery_index_self_lock",
"test_training_m87_release_index_final_closure_delivery_index_guard_self_lock",
"test_training_m88_release_index_final_closure_delivery_guard_source_self_lock",
guarded_method_name,
)
module_source = Path(__file__).read_text(encoding="utf-8")
module_tree = ast.parse(module_source)
functions_by_name = {
node.name: node
for node in ast.walk(module_tree)
if isinstance(node, ast.FunctionDef)
}
def local_assignment_node(method_name: str, local_name: str) -> ast.AST:
self.assertIn(method_name, functions_by_name)
assignments = tuple(
node.value
for node in ast.walk(functions_by_name[method_name])
if (
isinstance(node, ast.Assign)
and len(node.targets) == 1
and isinstance(node.targets[0], ast.Name)
and node.targets[0].id == local_name
)
)
self.assertEqual(len(assignments), 1)
return assignments[0]
role_mapping = ast.literal_eval(
local_assignment_node(
"test_training_m41_release_index_guard_inventory_is_current",
"required_guard_tests_by_role",
)
)
role_methods = tuple(role_mapping.values())
expected_inventory = ast.literal_eval(
local_assignment_node(
"test_training_m52_release_index_guard_inventory_order_and_uniqueness_self_lock",
"expected_inventory",
)
)
guarded_chain_names = tuple(
ast.literal_eval(local_assignment_node(guarded_method_name, local_name))
for local_name in (
"final_closure_guard_name",
"delivery_guard_name",
"source_guard_name",
"guard_name",
)
)
delivery_chain_node = local_assignment_node(
guarded_method_name,
"delivery_chain",
)
chain_methods_node = local_assignment_node(
guarded_method_name,
"chain_methods",
)
self.assertEqual(guarded_chain_names, expected_guard_chain_names)
self.assertIsInstance(delivery_chain_node, ast.Tuple)
self.assertEqual(len(delivery_chain_node.elts), 5)
self.assertIsInstance(delivery_chain_node.elts[0], ast.Starred)
self.assertIsInstance(delivery_chain_node.elts[0].value, ast.Name)
self.assertEqual(delivery_chain_node.elts[0].value.id, "closure_methods")
self.assertEqual(
tuple(
node.id
for node in delivery_chain_node.elts[1:]
if isinstance(node, ast.Name)
),
(
"final_closure_guard_name",
"delivery_guard_name",
"source_guard_name",
"guard_name",
),
)
self.assertIsInstance(chain_methods_node, ast.Subscript)
self.assertIsInstance(chain_methods_node.value, ast.Name)
self.assertEqual(chain_methods_node.value.id, "delivery_chain")
self.assertIsInstance(chain_methods_node.slice, ast.Slice)
self.assertIsInstance(chain_methods_node.slice.lower, ast.UnaryOp)
self.assertIsInstance(chain_methods_node.slice.lower.op, ast.USub)
self.assertIsInstance(chain_methods_node.slice.lower.operand, ast.Constant)
self.assertEqual(chain_methods_node.slice.lower.operand.value, 4)
self.assertIsNone(chain_methods_node.slice.upper)
self.assertIsNone(chain_methods_node.slice.step)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(guard_name),
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
guarded_method_name
)
+ 1,
)
self.assertEqual(
role_mapping.get(
"release_index_final_closure_delivery_guard_source_chain_source_shape_self_lock"
),
guard_name,
)
self.assertEqual(role_methods.count(guard_name), 1)
self.assertEqual(expected_inventory.count(guard_name), 1)
def test_training_m91_release_index_final_closure_delivery_guard_source_chain_source_shape_local_names_self_lock(
self,
) -> None:
guard_name = (
"test_training_m91_release_index_final_closure_delivery_guard_source_chain_source_shape_local_names_self_lock"
)
source_shape_guard_name = (
"test_training_m90_release_index_final_closure_delivery_guard_source_chain_source_shape_self_lock"
)
expected_local_names = (
"final_closure_guard_name",
"delivery_guard_name",
"source_guard_name",
"guard_name",
)
expected_lookup_source = (
"ast.literal_eval(local_assignment_node(guarded_method_name, local_name))"
)
module_source = Path(__file__).read_text(encoding="utf-8")
module_tree = ast.parse(module_source)
functions_by_name = {
node.name: node
for node in ast.walk(module_tree)
if isinstance(node, ast.FunctionDef)
}
def local_assignment_node(method_name: str, local_name: str) -> ast.AST:
self.assertIn(method_name, functions_by_name)
assignments = tuple(
node.value
for node in ast.walk(functions_by_name[method_name])
if (
isinstance(node, ast.Assign)
and len(node.targets) == 1
and isinstance(node.targets[0], ast.Name)
and node.targets[0].id == local_name
)
)
self.assertEqual(len(assignments), 1)
return assignments[0]
guarded_chain_names_node = local_assignment_node(
source_shape_guard_name,
"guarded_chain_names",
)
self.assertIsInstance(guarded_chain_names_node, ast.Call)
self.assertIsInstance(guarded_chain_names_node.func, ast.Name)
self.assertEqual(guarded_chain_names_node.func.id, "tuple")
self.assertEqual(len(guarded_chain_names_node.args), 1)
guarded_chain_generator = guarded_chain_names_node.args[0]
self.assertIsInstance(guarded_chain_generator, ast.GeneratorExp)
self.assertEqual(len(guarded_chain_generator.generators), 1)
generator_clause = guarded_chain_generator.generators[0]
self.assertIsInstance(generator_clause.target, ast.Name)
self.assertEqual(generator_clause.target.id, "local_name")
self.assertIsInstance(generator_clause.iter, ast.Tuple)
self.assertEqual(
ast.literal_eval(generator_clause.iter),
expected_local_names,
)
for element in generator_clause.iter.elts:
with self.subTest(local_name_node=ast.dump(element)):
self.assertIsInstance(element, ast.Constant)
self.assertIsInstance(element.value, str)
self.assertEqual(
ast.get_source_segment(module_source, guarded_chain_generator.elt),
expected_lookup_source,
)
self.assertIn(guard_name, TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.count(guard_name),
1,
)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.count(
source_shape_guard_name
),
1,
)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(guard_name),
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
source_shape_guard_name
)
+ 1,
)
def test_training_m92_release_index_final_closure_delivery_guard_source_chain_source_shape_local_names_registration_self_lock(
self,
) -> None:
guard_name = (
"test_training_m92_release_index_final_closure_delivery_guard_source_chain_source_shape_local_names_registration_self_lock"
)
local_names_guard_name = (
"test_training_m91_release_index_final_closure_delivery_guard_source_chain_source_shape_local_names_self_lock"
)
role_key = (
"release_index_final_closure_delivery_guard_source_chain_source_shape_local_names_registration_self_lock"
)
module_source = Path(__file__).read_text(encoding="utf-8")
module_tree = ast.parse(module_source)
test_case_name = f"{type(self).__module__}.{type(self).__qualname__}"
functions_by_name = {
node.name: node
for node in ast.walk(module_tree)
if isinstance(node, ast.FunctionDef)
}
def local_assignment_node(method_name: str, local_name: str) -> ast.AST:
self.assertIn(method_name, functions_by_name)
assignments = tuple(
node.value
for node in ast.walk(functions_by_name[method_name])
if (
isinstance(node, ast.Assign)
and len(node.targets) == 1
and isinstance(node.targets[0], ast.Name)
and node.targets[0].id == local_name
)
)
self.assertEqual(len(assignments), 1)
return assignments[0]
role_mapping = ast.literal_eval(
local_assignment_node(
"test_training_m41_release_index_guard_inventory_is_current",
"required_guard_tests_by_role",
)
)
role_methods = tuple(role_mapping.values())
expected_inventory = ast.literal_eval(
local_assignment_node(
"test_training_m52_release_index_guard_inventory_order_and_uniqueness_self_lock",
"expected_inventory",
)
)
registration_pair = (local_names_guard_name, guard_name)
local_names_guard_index = TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.index(
local_names_guard_name
)
self.assertEqual(role_mapping.get(role_key), guard_name)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY[
local_names_guard_index : local_names_guard_index
+ len(registration_pair)
],
registration_pair,
)
self.assertEqual(
tuple(method_name for method_name in role_methods if method_name in registration_pair),
registration_pair,
)
self.assertEqual(
tuple(
method_name
for method_name in expected_inventory
if method_name in registration_pair
),
registration_pair,
)
for method_name in registration_pair:
with self.subTest(method_name=method_name):
loader = unittest.TestLoader()
suite = loader.loadTestsFromName(f"{test_case_name}.{method_name}")
self.assertEqual(loader.errors, [])
self.assertEqual(suite.countTestCases(), 1)
self.assertEqual(
TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY.count(
method_name
),
1,
)
def test_training_m47_release_index_per_doc_helper_inventory_self_lock_is_current(self) -> None:
helper_name = "_release_index_missing_required_snippets_by_doc"
docs_guard_name = "test_training_readmes_expose_m1_m40_release_index_without_raw_test_modules"
inventory_guard_name = "test_training_m41_release_index_guard_inventory_is_current"
module_source = Path(__file__).read_text(encoding="utf-8")
module_tree = ast.parse(module_source)
functions_by_name = {
node.name: ast.get_source_segment(module_source, node) or ""
for node in ast.walk(module_tree)
if isinstance(node, ast.FunctionDef)
}
self.assertEqual(
[
node.name
for node in module_tree.body
if isinstance(node, ast.FunctionDef) and node.name == helper_name
],
[helper_name],
)
for guard_name in (docs_guard_name, inventory_guard_name):
with self.subTest(guard_name=guard_name):
self.assertIn(guard_name, functions_by_name)
self.assertIn(helper_name, functions_by_name[guard_name])
inventory_guard_source = functions_by_name[inventory_guard_name]
for fixture_reference in (
"PROJECT_README: missing_release_doc",
"TRAINING_PRODUCT_DOC: complete_release_doc",
"negative_fixture_missing_by_doc[TRAINING_PRODUCT_DOC], ()",
"negative_fixture_missing_by_doc[PROJECT_README]",
):
with self.subTest(fixture_reference=fixture_reference):
self.assertIn(fixture_reference, inventory_guard_source)
def test_training_m48_release_index_per_doc_helper_keeps_doc_tuple_shape(self) -> None:
complete_release_doc = "\n".join(TRAINING_M41_RELEASE_INDEX_DOC_SNIPPETS)
all_required_snippets = tuple(
(surface, snippet)
for surface, snippets in TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY
for snippet in snippets
)
expected_missing = tuple(
required_snippet
for required_snippet in all_required_snippets
if required_snippet[1]
in (CURRENT_TRAINING_DOC_MATURITY_MARKER, "API contract coverage")
)
missing_release_doc = complete_release_doc
for _, snippet in expected_missing:
missing_release_doc = missing_release_doc.replace(snippet, "", 1)
docs_by_name = {
"missing-release-index.md": missing_release_doc,
"complete-release-index.md": complete_release_doc,
}
original_docs_by_name = dict(docs_by_name)
missing_by_doc = _release_index_missing_required_snippets_by_doc(docs_by_name)
self.assertEqual(len(expected_missing), 2)
self.assertEqual(tuple(missing_by_doc), tuple(docs_by_name))
self.assertEqual(missing_by_doc["missing-release-index.md"], expected_missing)
self.assertIsInstance(missing_by_doc["missing-release-index.md"], tuple)
self.assertEqual(missing_by_doc["complete-release-index.md"], ())
self.assertIsInstance(missing_by_doc["complete-release-index.md"], tuple)
self.assertEqual(docs_by_name, original_docs_by_name)
def test_training_m49_release_index_per_doc_helper_handles_empty_docs_without_mutation(self) -> None:
complete_release_doc = "\n".join(TRAINING_M41_RELEASE_INDEX_DOC_SNIPPETS)
docs_by_name = {"complete-release-index.md": complete_release_doc}
original_docs_by_name = dict(docs_by_name)
empty_missing_by_doc = _release_index_missing_required_snippets_by_doc({})
complete_missing_by_doc = _release_index_missing_required_snippets_by_doc(docs_by_name)
self.assertEqual(empty_missing_by_doc, {})
self.assertEqual(docs_by_name, original_docs_by_name)
self.assertEqual(complete_missing_by_doc["complete-release-index.md"], ())
def test_training_m50_release_index_helper_accepts_flattened_inventory_complete_doc(self) -> None:
flattened_required_snippets = tuple(
snippet
for _, snippets in TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY
for snippet in snippets
)
complete_release_doc = "\n".join(flattened_required_snippets)
docs_by_name = {"synthetic-complete-release.md": complete_release_doc}
missing_by_doc = _release_index_missing_required_snippets_by_doc(docs_by_name)
self.assertTrue(flattened_required_snippets)
self.assertEqual(len(flattened_required_snippets), len(set(flattened_required_snippets)))
self.assertEqual(missing_by_doc, {"synthetic-complete-release.md": ()})
def test_training_m54_release_index_required_snippet_inventory_category_shape_is_locked(self) -> None:
inventory = TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY
inventory_by_category = dict(inventory)
expected_categories = (
"current_m1_m40_marker",
"acceptance_offline_validation",
"public_api_privacy_contracts",
"package_smoke_offline_registry",
"dashboard_public_docs_privacy",
"single_set_docker_deployment",
"docker_smoke_guard_coverage",
)
flattened_snippets = tuple(
snippet
for category in expected_categories
for snippet in inventory_by_category[category]
)
self.assertEqual(tuple(category for category, _ in inventory), expected_categories)
self.assertEqual(len(expected_categories), len(set(expected_categories)))
for category in expected_categories:
with self.subTest(category=category):
snippets = inventory_by_category[category]
self.assertTrue(snippets)
for snippet in snippets:
self.assertIsInstance(snippet, str)
self.assertNotEqual(snippet, "")
self.assertEqual(TRAINING_M41_RELEASE_INDEX_DOC_SNIPPETS, flattened_snippets)
self.assertEqual(len(flattened_snippets), len(set(flattened_snippets)))
@staticmethod
def _release_index_required_snippet_inventory_source_categories(
module_source: str,
) -> tuple[str, ...]:
inventory_name = "TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY"
def assignment_targets(node: ast.AST):
if isinstance(node, ast.Assign):
return tuple(node.targets)
if isinstance(node, (ast.AnnAssign, ast.AugAssign)):
return (node.target,)
return ()
module_tree = ast.parse(module_source)
inventory_assignments = tuple(
node
for node in module_tree.body
if any(
isinstance(target, ast.Name) and target.id == inventory_name
for target in assignment_targets(node)
)
)
if len(inventory_assignments) != 1:
raise AssertionError(
"release index required snippet inventory must have one assignment"
)
inventory_source = getattr(inventory_assignments[0], "value", None)
if not isinstance(inventory_source, ast.Tuple):
raise AssertionError(
"release index required snippet inventory must be a literal tuple assignment"
)
disallowed_source_nodes = (
ast.Call,
ast.Dict,
ast.DictComp,
ast.GeneratorExp,
ast.ListComp,
ast.SetComp,
ast.Starred,
)
dynamic_source_node = next(
(
node
for node in ast.walk(inventory_source)
if isinstance(node, disallowed_source_nodes)
),
None,
)
if dynamic_source_node is not None:
dynamic_node = type(dynamic_source_node).__name__
raise AssertionError(
"release index required snippet inventory uses dynamic source node "
f"{dynamic_node}"
)
try:
inventory = ast.literal_eval(inventory_source)
except (SyntaxError, ValueError) as exc:
raise AssertionError(
"release index required snippet inventory must use literal snippets"
) from exc
if not all(
isinstance(group, tuple)
and len(group) == 2
and isinstance(group[0], str)
and isinstance(group[1], (tuple, list))
and group[1]
and all(isinstance(snippet, str) and snippet for snippet in group[1])
for group in inventory
):
raise AssertionError(
"release index required snippet inventory groups must be "
"literal category and snippet pairs"
)
return tuple(category for category, _ in inventory)
def test_training_m55_release_index_required_snippet_inventory_source_shape_is_locked(self) -> None:
module_source = Path(__file__).read_text(encoding="utf-8")
expected_categories = (
"current_m1_m40_marker",
"acceptance_offline_validation",
"public_api_privacy_contracts",
"package_smoke_offline_registry",
"dashboard_public_docs_privacy",
"single_set_docker_deployment",
"docker_smoke_guard_coverage",
)
source_group_order = (
self._release_index_required_snippet_inventory_source_categories(
module_source
)
)
self.assertEqual(source_group_order, expected_categories)
def test_training_m56_release_index_required_snippet_inventory_source_shape_rejects_dynamic_fixtures(
self,
) -> None:
inventory_name = "TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY"
invalid_sources = {
"dict_assignment": (
f"{inventory_name} = {{'literal_category': ('literal snippet',)}}",
"literal tuple assignment",
),
"call_snippets": (
f"{inventory_name} = (('literal_category', make_snippets()),)",
"dynamic source node Call",
),
"name_snippets": (
f"{inventory_name} = (('literal_category', snippets),)",
"must use literal snippets",
),
"starred_snippets": (
f"{inventory_name} = (('literal_category', (*('literal snippet',),)),)",
"dynamic source node Starred",
),
"comprehension_snippets": (
f"{inventory_name} = "
"(('literal_category', [item for item in ('literal snippet',)]),)",
"dynamic source node ListComp",
),
}
for fixture_name, (source, error_snippet) in invalid_sources.items():
with self.subTest(fixture_name=fixture_name):
with self.assertRaisesRegex(AssertionError, re.escape(error_snippet)):
self._release_index_required_snippet_inventory_source_categories(
source
)
def test_training_m57_release_index_required_snippet_inventory_source_shape_diagnostics_are_locked(
self,
) -> None:
inventory_name = "TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY"
group_shape_error = "literal category and snippet pairs"
invalid_sources = {
"zero_inventory_assignment": (
"UNRELATED_RELEASE_INDEX_INVENTORY = ()",
"must have one assignment",
),
"duplicate_inventory_assignment": (
f"{inventory_name} = (('literal_category', ('literal snippet',)),)\n"
f"{inventory_name} = (('second_literal_category', ('second literal snippet',)),)",
"must have one assignment",
),
"malformed_group_tuple": (
f"{inventory_name} = (('literal_category', ('literal snippet',), 'extra'),)",
group_shape_error,
),
"empty_snippet_group": (
f"{inventory_name} = (('literal_category', ()),)",
group_shape_error,
),
"non_string_category": (
f"{inventory_name} = ((7, ('literal snippet',)),)",
group_shape_error,
),
"non_string_snippet": (
f"{inventory_name} = (('literal_category', (7,)),)",
group_shape_error,
),
"empty_snippet": (
f"{inventory_name} = (('literal_category', ('',)),)",
group_shape_error,
),
}
for fixture_name, (source, error_snippet) in invalid_sources.items():
with self.subTest(fixture_name=fixture_name):
with self.assertRaisesRegex(AssertionError, re.escape(error_snippet)):
self._release_index_required_snippet_inventory_source_categories(
source
)
def test_training_m58_release_index_required_snippet_inventory_source_shape_accepts_literal_fixtures(
self,
) -> None:
source = """
TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY = (
(
"gamma_literal_category",
(
"gamma release note",
"gamma release detail",
),
),
(
"alpha_literal_category",
[
"alpha release note",
"alpha release detail",
],
),
(
"beta_literal_category",
(
"beta release note",
),
),
)
"""
expected_categories = (
"gamma_literal_category",
"alpha_literal_category",
"beta_literal_category",
)
source_group_order = (
self._release_index_required_snippet_inventory_source_categories(source)
)
self.assertEqual(source_group_order, expected_categories)
self.assertNotEqual(source_group_order, tuple(sorted(source_group_order)))
def test_training_m59_release_index_required_snippet_inventory_source_shape_preserves_literal_order(
self,
) -> None:
source = """
TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY = (
(
"literal_order_third_category",
(
"third literal order signal",
),
),
(
"literal_order_first_category",
(
"first literal order signal",
),
),
(
"literal_order_second_category",
(
"second literal order signal",
),
),
)
"""
expected_categories = (
"literal_order_third_category",
"literal_order_first_category",
"literal_order_second_category",
)
source_group_order = (
self._release_index_required_snippet_inventory_source_categories(source)
)
self.assertNotEqual(expected_categories, tuple(sorted(expected_categories)))
self.assertEqual(source_group_order, expected_categories)
def test_training_m53_release_index_doc_category_coverage_is_exact(self) -> None:
inventory = TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY
inventory_by_category = dict(inventory)
expected_categories = tuple(category for category, _ in inventory)
expected_complete_results = {
category: (inventory_by_category[category], ())
for category in expected_categories
}
def category_results(text: str):
missing_pairs = _release_index_missing_required_snippets_by_doc(
{"release-index-doc.md": text}
)["release-index-doc.md"]
missing_by_category = {
category: tuple(
snippet
for missing_category, snippet in missing_pairs
if missing_category == category
)
for category in expected_categories
}
return {
category: (
tuple(
snippet
for snippet in inventory_by_category[category]
if snippet not in missing_by_category[category]
),
missing_by_category[category],
)
for category in expected_categories
}
for path in TRAINING_M41_RELEASE_INDEX_DOCS:
with self.subTest(path=path.name):
self.assertEqual(
category_results(path.read_text(encoding="utf-8")),
expected_complete_results,
)
synthetic_missing_category = expected_categories[-1]
synthetic_missing_doc = "\n".join(
snippet
for category in expected_categories
if category != synthetic_missing_category
for snippet in inventory_by_category[category]
)
expected_missing_results = dict(expected_complete_results)
expected_missing_results[synthetic_missing_category] = (
(),
inventory_by_category[synthetic_missing_category],
)
self.assertEqual(
category_results(synthetic_missing_doc),
expected_missing_results,
)
def test_training_m41_release_index_inventory_shape_is_stable(self) -> None:
module_tree = ast.parse(Path(__file__).read_text(encoding="utf-8"))
inventory_assignments = [
node
for node in module_tree.body
if isinstance(node, ast.Assign)
for target in node.targets
if (
isinstance(target, ast.Name)
and target.id == "TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY"
)
]
expected_group_order = (
"current_m1_m40_marker",
"acceptance_offline_validation",
"public_api_privacy_contracts",
"package_smoke_offline_registry",
"dashboard_public_docs_privacy",
"single_set_docker_deployment",
"docker_smoke_guard_coverage",
)
grouped_inventory = TRAINING_M41_RELEASE_INDEX_REQUIRED_SNIPPET_INVENTORY
grouped_snippets = tuple(
snippet
for _, snippets in grouped_inventory
for snippet in snippets
)
active_release_inventory = (
*TRAINING_M41_RELEASE_INDEX_GUARD_TEST_INVENTORY,
*(category for category, _ in grouped_inventory),
*grouped_snippets,
CURRENT_TRAINING_DOC_MATURITY_MARKER,
CURRENT_TRAINING_DOC_MATURITY_SPAN,
)
self.assertEqual(len(inventory_assignments), 1)
inventory_source = inventory_assignments[0].value
self.assertIsInstance(inventory_source, ast.Tuple)
source_group_order = tuple(
ast.literal_eval(group_node.elts[0])
for group_node in inventory_source.elts
if isinstance(group_node, ast.Tuple) and len(group_node.elts) == 2
)
self.assertEqual(source_group_order, expected_group_order)
self.assertEqual(len(source_group_order), len(set(source_group_order)))
self.assertEqual(tuple(category for category, _ in grouped_inventory), expected_group_order)
for group_name, snippets in grouped_inventory:
with self.subTest(group_name=group_name):
self.assertTrue(snippets)
self.assertEqual(TRAINING_M41_RELEASE_INDEX_DOC_SNIPPETS, grouped_snippets)
self.assertEqual(len(grouped_snippets), len(set(grouped_snippets)))
self.assertIn("M1-M40", active_release_inventory)
self.assertIn("through M40", active_release_inventory)
for stale_value in (
*TRAINING_M41_STALE_RELEASE_INVENTORY_NAMES,
"M1-M39",
"through M39",
):
with self.subTest(stale_value=stale_value):
self.assertNotIn(stale_value, active_release_inventory)
def test_local_docker_deployment_documentation_guard_inventory_is_current(self) -> None:
module_path = Path(__file__)
module_source = module_path.read_text(encoding="utf-8")
module_tree = ast.parse(module_source)
class_nodes = [
node
for node in module_tree.body
if isinstance(node, ast.ClassDef) and node.name == "DocumentationConsistencyTests"
]
top_level_names = {
target.id
for node in module_tree.body
if isinstance(node, ast.Assign)
for target in node.targets
if isinstance(target, ast.Name)
}
required_guard_tests = {
"test_readmes_describe_single_set_local_docker_deployment_policy",
"test_readmes_lock_single_set_docker_smoke_command_shape",
}
inventory_names = tuple(LOCAL_DOCKER_DOCUMENTATION_GUARD_TEST_INVENTORY)
self.assertEqual(len(class_nodes), 1)
self.assertEqual(len(inventory_names), len(set(inventory_names)))
self.assertLessEqual(required_guard_tests, set(inventory_names))
test_names = {
item.name
for item in class_nodes[0].body
if isinstance(item, ast.FunctionDef) and item.name.startswith("test_")
}
for name in inventory_names:
with self.subTest(name=name):
loader = unittest.TestLoader()
suite = loader.loadTestsFromName(
f"{type(self).__module__}.DocumentationConsistencyTests.{name}"
)
self.assertIn(name, test_names)
self.assertEqual(loader.errors, [])
self.assertGreater(suite.countTestCases(), 0)
for constant_name in LOCAL_DOCKER_DOCUMENTATION_GUARD_SOURCE_CONSTANTS:
with self.subTest(constant_name=constant_name):
self.assertIn(constant_name, top_level_names)
self.assertIn(f"{constant_name} =", module_source)
def test_training_case_acceptance_manifest_modules_are_discoverable(self) -> None:
manifest_modules = tuple(TRAINING_CASE_ACCEPTANCE_TEST_MANIFEST)
missing_modules = [
module
for module in TRAINING_CASE_REQUIRED_ACCEPTANCE_TEST_MODULES
if module not in manifest_modules
]
self.assertEqual(missing_modules, [])
self.assertEqual(len(manifest_modules), len(set(manifest_modules)))
for module in manifest_modules:
with self.subTest(module=module):
path = ROOT / "tests" / "unit" / f"{module}.py"
loader = unittest.TestLoader()
suite = loader.loadTestsFromName(f"tests.unit.{module}")
self.assertTrue(path.is_file(), path)
self.assertEqual(loader.errors, [])
self.assertGreater(suite.countTestCases(), 0)
def test_training_readmes_name_dashboard_privacy_and_offline_registry_coverage(self) -> None:
expected_doc_snippets = (
"dashboard and public docs privacy smoke coverage",
"dashboard_js_syntax",
"training_case_package",
)
for path in (PROJECT_README, TRAINING_PRODUCT_DOC):
text = path.read_text(encoding="utf-8")
with self.subTest(path=path.name):
for snippet in expected_doc_snippets:
self.assertIn(snippet, text)
registry_text = OFFLINE_CHECKS_SCRIPT.read_text(encoding="utf-8")
for check_name in ("dashboard_js_syntax", "training_case_package"):
with self.subTest(check_name=check_name):
self.assertEqual(registry_text.count(f'"{check_name}"'), 1)
def test_training_readmes_describe_acceptance_manifest_offline_validation_posture(self) -> None:
for path in (PROJECT_README, TRAINING_PRODUCT_DOC):
text = path.read_text(encoding="utf-8")
with self.subTest(path=path.name):
for snippet in TRAINING_ACCEPTANCE_VALIDATION_DOC_SNIPPETS:
self.assertIn(snippet, text)
for path in TRAINING_PUBLIC_PRIVACY_DOCS:
text = path.read_text(encoding="utf-8")
with self.subTest(path=path.name, surface="manifest_modules"):
for module in TRAINING_CASE_ACCEPTANCE_TEST_MANIFEST:
self.assertNotIn(module, text)
def test_readmes_describe_single_set_local_docker_deployment_policy(self) -> None:
for path in LOCAL_DOCKER_POLICY_DOCS:
text = path.read_text(encoding="utf-8")
lower_text = text.lower()
with self.subTest(path=path.name):
for snippet in LOCAL_DOCKER_POLICY_REQUIRED_SNIPPETS:
self.assertIn(snippet, text)
self.assertLess(
lower_text.index("down --remove-orphans"),
lower_text.index("up -d --build"),
)
for forbidden in LOCAL_DOCKER_POLICY_FORBIDDEN_ENCOURAGEMENT:
self.assertNotIn(forbidden, lower_text)
def test_readmes_lock_single_set_docker_smoke_command_shape(self) -> None:
command_lines_by_path = {
path: _local_docker_command_lines(_local_docker_deployment_section(path))
for path in LOCAL_DOCKER_POLICY_DOCS
}
expected_commands = LOCAL_DOCKER_REBUILD_COMMANDS + LOCAL_DOCKER_SMOKE_COMMANDS
self.assertEqual(
command_lines_by_path[PROJECT_README],
command_lines_by_path[TRAINING_PRODUCT_DOC],
)
for path, command_lines in command_lines_by_path.items():
with self.subTest(path=path.name):
for command in expected_commands:
self.assertIn(command, command_lines)
self.assertLess(
command_lines.index(LOCAL_DOCKER_REBUILD_COMMANDS[0]),
command_lines.index(LOCAL_DOCKER_REBUILD_COMMANDS[1]),
)
for command in command_lines:
if command.startswith("docker compose"):
self.assertTrue(command.startswith(LOCAL_DOCKER_COMPOSE_PREFIX), command)
self.assertNotIn("docker compose -p ai-ict down --remove-orphans", command_lines)
self.assertNotIn("docker compose -p ai-ict up -d --build", command_lines)
def test_training_case_product_doc_names_public_response_privacy_contracts(self) -> None:
text = TRAINING_PRODUCT_DOC.read_text(encoding="utf-8")
for snippet in (
"case list/detail",
"package export/import",
"progress",
"submit",
"create-attempt",
"annotation lifecycle",
"privacy contract tests",
"scrub private solution material",
"internal solution details",
):
with self.subTest(snippet=snippet):
self.assertIn(snippet, text)
self.assertNotIn("private " + "answer", text.lower())
self.assertNotIn("answer " + "detail", text.lower())
def test_training_case_product_doc_api_routes_match_server_route_request(self) -> None:
documented_routes = _training_api_routes_from_product_doc()
server_routes = _supported_training_routes_from_route_request()
self.assertEqual(
len(documented_routes),
len(set(documented_routes)),
"Training API docs contain duplicate route entries",
)
self.assertEqual(
sorted(documented_routes),
sorted(server_routes),
)
def test_training_case_public_route_registry_is_documented_and_supported(self) -> None:
documented_routes = set(_training_api_routes_from_product_doc())
server_routes = set(_supported_training_routes_from_route_request())
missing_from_docs = [
route for route in TRAINING_PUBLIC_API_ROUTE_REGISTRY if route not in documented_routes
]
missing_from_server = [
route for route in TRAINING_PUBLIC_API_ROUTE_REGISTRY if route not in server_routes
]
self.assertEqual(missing_from_docs, [])
self.assertEqual(missing_from_server, [])
def test_training_case_product_doc_api_surface_wording_matches_public_routes(self) -> None:
capabilities = {
(method, path): capability
for method, path, capability in _training_api_surface_rows_from_product_doc()
}
server_routes = set(_supported_training_routes_from_route_request())
self.assertEqual(sorted(capabilities), sorted(TRAINING_PUBLIC_API_ROUTE_REGISTRY))
for route, snippets in TRAINING_ROUTE_SURFACE_WORDING.items():
with self.subTest(route=route):
self.assertIn(route, server_routes)
for snippet in snippets:
self.assertIn(snippet, capabilities[route])
def test_training_dashboard_routes_are_documented_public_api_routes(self) -> None:
dashboard_routes = _training_dashboard_routes_from_app()
dashboard_paths = _training_dashboard_fetch_paths_from_app()
documented_routes = set(_training_api_routes_from_product_doc())
server_routes = set(_supported_training_routes_from_route_request())
self.assertEqual(dashboard_routes, TRAINING_DASHBOARD_ROUTE_REGISTRY)
self.assertEqual(dashboard_paths, tuple(path for _method, path in TRAINING_DASHBOARD_ROUTE_REGISTRY))
for route in dashboard_routes:
with self.subTest(route=route):
self.assertIn(route, TRAINING_PUBLIC_API_ROUTE_REGISTRY)
self.assertIn(route, documented_routes)
self.assertIn(route, server_routes)
def test_training_dashboard_and_public_docs_keep_privacy_wording_exclusionary(self) -> None:
dashboard_section = _training_product_doc_section("Dashboard Entry").lower()
dashboard_source = "\n".join(
path.read_text(encoding="utf-8").lower()
for path in (TRAINING_DASHBOARD_HTML, TRAINING_DASHBOARD_APP)
)
for snippet in TRAINING_DASHBOARD_PUBLIC_WORDING:
with self.subTest(snippet=snippet):
self.assertIn(snippet, dashboard_section)
for term in TRAINING_PUBLIC_PRIVACY_FORBIDDEN_TERMS:
with self.subTest(surface="dashboard", term=term):
self.assertNotIn(term, dashboard_source)
for phrase in TRAINING_PUBLIC_PRIVACY_MATERIAL_PHRASES:
with self.subTest(surface="dashboard", phrase=phrase):
self.assertNotIn(phrase, dashboard_source)
for path in TRAINING_PUBLIC_PRIVACY_DOCS:
text = path.read_text(encoding="utf-8")
lower_text = text.lower()
privacy_lines = _training_public_privacy_lines(text)
with self.subTest(path=path.name):
self.assertTrue(privacy_lines)
for term in TRAINING_PUBLIC_PRIVACY_FORBIDDEN_TERMS:
self.assertNotIn(term, lower_text)
for line in privacy_lines:
self.assertTrue(
any(word in line for word in TRAINING_PUBLIC_PRIVACY_EXCLUSION_WORDS),
line,
)
def test_training_case_product_doc_names_public_error_semantics(self) -> None:
section = _training_validation_section()
for snippet in (
"`400` with `invalid_json_body`",
"`400` with `invalid_path_param:<field>`",
"`400` with `invalid_limit_query_param:limit`",
"`404` with `not_found`",
"`500` with `internal_server_error`",
"do not echo raw internals",
):
with self.subTest(snippet=snippet):
self.assertIn(snippet, section)
self.assertNotIn("answer" + "_key", section)
def test_training_readmes_publish_public_error_catalog(self) -> None:
for path in TRAINING_PUBLIC_ERROR_DOCS:
text = path.read_text(encoding="utf-8")
with self.subTest(path=path.name):
for snippet in TRAINING_PUBLIC_ERROR_CATALOG_SNIPPETS:
self.assertIn(snippet, text)
def test_training_public_error_docs_avoid_raw_stack_and_os_error_wording(self) -> None:
for path in TRAINING_PUBLIC_ERROR_RAW_WORDING_DOCS:
text = path.read_text(encoding="utf-8").lower()
with self.subTest(path=path.name):
for forbidden in TRAINING_PUBLIC_ERROR_FORBIDDEN_RAW_WORDING:
self.assertNotIn(forbidden.lower(), text)
def test_training_case_product_doc_avoids_private_literal_shapes(self) -> None:
text = TRAINING_PRODUCT_DOC.read_text(encoding="utf-8").lower()
for term in (
"data" + "base",
"data" + "base_url",
"post" + "gresql",
"psy" + "copg",
"pass" + "word",
"pass" + "wd",
"tok" + "en",
"sec" + "ret",
"api" + "_key",
"answer" + "_key",
):
with self.subTest(term=term):
self.assertNotIn(term, text)
self.assertIsNone(re.search(r"\b(?:\d{1,3}\.){3}\d{1,3}\b", text))
if __name__ == "__main__":
unittest.main()