Ctrl K
ComunidadGuías…

tests/test_extractor_scan_root_context.py

Rama v8 · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""The in-flight scan root is shared through extractors.base, not by reaching
back into graphify.extract — MIGRATION.md invariant #4 (#3666)."""
from __future__ import annotations

import ast
from pathlib import Path

from graphify.extractors import base as base_mod
from graphify.extractors import markdown as markdown_mod


def _imports_graphify_extract(module) -> bool:
    """True if the module's source imports graphify.extract anywhere — a
    top-level or a function-local `import graphify.extract` / `from
    graphify.extract import ...`."""
    source = Path(module.__file__).read_text(encoding="utf-8")
    for node in ast.walk(ast.parse(source)):
        if isinstance(node, ast.Import):
            if any(a.name == "graphify.extract" or a.name.startswith("graphify.extract.")
                   for a in node.names):
                return True
        elif isinstance(node, ast.ImportFrom):
            if node.module == "graphify.extract" or (node.module or "").startswith("graphify.extract."):
                return True
    return False


def test_markdown_extractor_does_not_import_graphify_extract():
    """The Markdown extractor read the in-flight scan root via a function-local
    `import graphify.extract` + getattr, a package->parent dependency that
    violated invariant #4 and degraded silently on a rename (#3666). It must now
    reach the shared context through extractors.base instead."""
    assert not _imports_graphify_extract(markdown_mod), (
        "extractors/markdown.py must not import graphify.extract — read the scan "
        "root via extractors.base.active_scan_root() (MIGRATION.md invariant #4)"
    )


def test_active_scan_root_defaults_to_none():
    # A fresh process (no extraction in flight) has no active root.
    assert base_mod.active_scan_root() is None


def test_active_scan_root_set_get_restore_nested():
    """set_active_scan_root returns the previous value so nested extraction can
    restore it; active_scan_root reflects the current top of that stack."""
    assert base_mod.active_scan_root() is None
    outer = Path("/repo").resolve()
    inner = Path("/repo/vendored").resolve()

    prev_outer = base_mod.set_active_scan_root(outer)
    try:
        assert prev_outer is None
        assert base_mod.active_scan_root() == outer

        prev_inner = base_mod.set_active_scan_root(inner)
        try:
            assert prev_inner == outer
            assert base_mod.active_scan_root() == inner
        finally:
            base_mod.set_active_scan_root(prev_inner)

        assert base_mod.active_scan_root() == outer
    finally:
        base_mod.set_active_scan_root(prev_outer)

    assert base_mod.active_scan_root() is None


def test_markdown_active_scan_root_alias_is_base_accessor():
    """The Markdown extractor's _active_scan_root is the base accessor, so the
    scan root extract() publishes is exactly what link resolution reads."""
    assert markdown_mod._active_scan_root is base_mod.active_scan_root