Ctrl K
ComunidadGuías…

tests/test_elixir_defdelegate.py

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

Archivo original ↗Preguntar a KiBot
"""`defdelegate` defines an invocable function in the module (#4132).

`defdelegate greet(name), to: Greeter` declares a callable `greet` whose body is
delegated to another module. It has the same `call` head shape as `def`, but was
missing from the def-family recognizer, so no node was minted and same-module
calls to the delegated name dangled.
"""
from __future__ import annotations

from pathlib import Path

from graphify.extract import extract


def _graph(tmp_path: Path):
    src = tmp_path / "facade.ex"
    src.write_text(
        "defmodule Facade do\n"
        "  defdelegate start(x), to: Worker\n"
        "  defdelegate stop(x), to: Worker, as: :halt\n"
        "  def run(x) do\n"
        "    start(x)\n"
        "    stop(x)\n"
        "  end\n"
        "end\n",
        encoding="utf-8",
    )
    result = extract([src], cache_root=tmp_path / "graphify-out")
    label = {n["id"]: n["label"] for n in result["nodes"]}
    return result, label


def _edges(result, label, relation):
    return {
        (label[e["source"]], label[e["target"]])
        for e in result["edges"]
        if e["relation"] == relation and e["source"] in label and e["target"] in label
    }


def test_defdelegate_defines_functions(tmp_path: Path) -> None:
    result, label = _graph(tmp_path)
    labels = set(label.values())
    assert "start()" in labels, "defdelegate function dropped"
    assert "stop()" in labels, "defdelegate-with-as function dropped"
    methods = _edges(result, label, "method")
    assert ("Facade", "start()") in methods
    assert ("Facade", "stop()") in methods


def test_defdelegate_same_module_calls_resolve(tmp_path: Path) -> None:
    result, label = _graph(tmp_path)
    calls = _edges(result, label, "calls")
    assert ("run()", "start()") in calls, "call to a delegated function dangled"
    assert ("run()", "stop()") in calls


def test_defdelegate_leaves_no_dangling_edges(tmp_path: Path) -> None:
    result, _ = _graph(tmp_path)
    node_ids = {n["id"] for n in result["nodes"]}
    dangling = [
        e for e in result["edges"]
        if e["source"] not in node_ids or e["target"] not in node_ids
    ]
    assert not dangling, f"defdelegate produced dangling edges: {dangling}"