from textwrap import dedent

from johnnydep.lib import JohnnyDist
from johnnydep.dot import jd2dot


def test_dot_export(make_dist):
    deps = ["child>0.1"]
    extras = {"x": ["extra"]}
    make_dist(name="parent", install_requires=deps, extras_require=extras)
    make_dist(name="child")
    make_dist(name="Extra")
    dist = JohnnyDist("parent[x]")
    actual = dist.serialise(format="dot")
    expected = dedent(
        """
        # generated by https://github.com/wimglenn/johnnydep v1.0
        digraph parent {
            "parent[x]" -> "child" [label=">0.1"];
            "parent[x]" -> "Extra";
        }
        """
    ).strip()
    assert actual == expected


def test_nodupes(make_dist):
    make_dist(name="root", install_requires=["dep1", "dep2"])
    make_dist(name="dep1", install_requires=["leaf"])
    make_dist(name="dep2", install_requires=["leaf"])
    make_dist(name="leaf")
    dist = JohnnyDist("root")
    actual = jd2dot(dist, comment="// diamond")
    expected = dedent(
        """
        // diamond
        digraph root {
            "root" -> "dep1";
            "root" -> "dep2";
            "dep1" -> "leaf";
            "dep2" -> "leaf";
        }
        """
    ).strip()
    assert actual == expected


def test_circular_graph(make_dist):
    make_dist(name="dist1", install_requires=["dist2"])
    make_dist(name="dist2", install_requires=["dist3"])
    make_dist(name="dist3", install_requires=["dist1"])
    dist = JohnnyDist("dist1")
    actual = jd2dot(dist, comment="cyclic, oh no!")
    expected = dedent(
        """
        # cyclic, oh no!
        digraph dist1 {
            "dist1" -> "dist2";
            "dist2" -> "dist3";
            "dist3" -> "dist1";
        }
        """
    ).strip()
    assert actual == expected


def test_graph_with_no_edges(make_dist):
    make_dist(name="lonely")
    dist = JohnnyDist("lonely")
    actual = jd2dot(dist, comment="")
    expected = dedent(
        """
        digraph lonely {
            "lonely";
        }
        """
    ).strip()
    assert actual == expected
