pipecircuit-visualization 0.0.9

Code-derived architectural visualizations for Pipecircuit programs
Documentation
use super::*;
use pipecircuit::{BindingDescription, DeclarationLocation, DescribeBindings, Pipe};
struct Protocol;
impl Pipe for Protocol {
    type In<'a> = &'a [u8];
    type Out<'a> = usize;
}
pipecircuit::pipe_roster! { mod roster {
    /// A client sends data & observes results.
    #[doc = concat!(" Additional ", "detail.")]
    client: super::Protocol,
    worker: super::Protocol
} }
struct Board;
impl Switchboard for Board {
    type From<'a> = roster::From<'a>;
    type To<'a> = roster::To<'a>;
    fn route<'a>(&mut self, from: Self::From<'a>) -> pipecircuit::Route<Self::To<'a>> {
        pipecircuit::Route::one({
            match from {
                roster::From::Client(_) => roster::To::Worker(&[]),
                roster::From::Worker(_) => roster::To::Client(&[]),
            }
        })
    }
}
struct FixtureBinding;
impl DescribeBindings for FixtureBinding {
    type Roster = roster::Schema;
    fn describe_bindings(&self) -> impl ExactSizeIterator<Item = BindingDescription> {
        let client = BindingDescription {
            name: "client",
            documentation: &[" Queue <script>alert(1)</script> & \"owned\" data."],
            binding: "Carrier<\"bytes\">",
            driver: "Driver",
            declaration: DeclarationLocation {
                package: "fixture",
                file: "src/example.rs",
                line: 3,
                column: 5,
            },
        };
        [
            client,
            BindingDescription {
                name: "worker",
                ..client
            },
        ]
        .into_iter()
    }
}
#[test]
fn compiled_protocol_metadata_is_ordered_and_preserves_lending_families() -> Result<(), &'static str>
{
    let diagram = ProgramDiagram::<roster::Schema>::for_board::<Board>();
    assert_eq!(diagram.board(), core::any::type_name::<Board>());
    let [client, worker] = diagram.pipes() else {
        return Err("wrong roster");
    };
    assert_eq!(client.name, "client");
    assert_eq!(worker.name, "worker");
    assert_eq!(client.protocol, worker.protocol);
    assert_eq!(client.input, "&[u8]");
    assert_eq!(client.output, "usize");
    assert!(client.declaration.file.ends_with("program/tests.rs"));
    assert!(client.declaration.line > 0);
    assert_ne!(client.declaration.line, worker.declaration.line);
    assert_eq!(
        client.documentation,
        &[
            " A client sends data & observes results.",
            " Additional detail."
        ]
    );
    let before = diagram.render(DiagramTarget::TextTree);
    assert!(before.contains("runtime routes and reachability are not inferred"));
    let physical = diagram.installed(&FixtureBinding);
    assert_eq!(
        physical.bindings(),
        FixtureBinding.describe_bindings().collect::<Vec<_>>(),
    );
    assert_eq!(before, diagram.render(DiagramTarget::TextTree));
    assert!(physical.render(DiagramTarget::TextTree).contains(
        "Transport occupancy, health, remote placement and compatibility are not measured here"
    ));
    for target in [DiagramTarget::MermaidFlowchart, DiagramTarget::GraphvizDot] {
        let rendered = physical.render(target);
        assert!(rendered.contains("installed as"));
        assert!(rendered.contains("src/example.rs:3:5"));
    }
    assert!(
        physical
            .render(DiagramTarget::MermaidFlowchart)
            .contains("Carrier&lt;&quot;bytes&quot;&gt;")
    );
    assert!(
        physical
            .render(DiagramTarget::GraphvizDot)
            .contains("Carrier<\\\"bytes\\\">")
    );
    Ok(())
}

#[test]
fn html_preserves_direction_and_escapes_author_content() {
    let diagram = ProgramDiagram::<roster::Schema>::for_board::<Board>();
    let semantic = diagram.render_html();
    assert!(semantic.contains("Emits to switchboard<code>usize</code>"));
    assert!(semantic.contains("Receives from switchboard<code>&amp;[u8]</code>"));
    assert!(semantic.contains("A client sends data &amp; observes results."));
    assert!(!semantic.contains("id=\"placement\""));
    let physical = diagram.installed(&FixtureBinding).render_html();
    assert!(physical.contains("Show physical installation"));
    assert!(physical.contains("&lt;script&gt;alert(1)&lt;/script&gt;"));
    assert!(!physical.contains("<script>"));
    assert!(physical.contains("Carrier&lt;&quot;bytes&quot;&gt;"));
    assert!(physical.contains("src/example.rs:3:5"));
    assert!(physical.contains("static inspection artifact, not a live monitor"));
}

#[test]
fn missing_binding_documentation_uses_the_escaped_driver_name() {
    let pipes = roster::Schema::describe_pipes().collect::<Vec<_>>();
    let bindings = FixtureBinding
        .describe_bindings()
        .map(|binding| BindingDescription {
            documentation: &[],
            driver: "transport::Driver_2<&'a \"bytes\">",
            ..binding
        })
        .collect::<Vec<_>>();
    let rendered = html::render("Board", &pipes, Some(&bindings));
    assert_eq!(
        rendered
            .matches("<p class=\"note\">Driver_2&lt;&amp;&#39;a &quot;bytes&quot;&gt;</p>")
            .count(),
        2
    );
    assert!(
        rendered.contains("<code>transport::Driver_2&lt;&amp;&#39;a &quot;bytes&quot;&gt;</code>")
    );
}

#[test]
fn abbreviated_types_preserve_punctuation_unicode_and_identifier_parts() {
    for (qualified, expected) in [
        ("", ""),
        ("app::Board_2", "Board_2"),
        (
            "outer::Pair<first::Left_1, second::Right_2>",
            "Pair<Left_1, Right_2>",
        ),
        ("&'a [outer::Élément_2; 7]", "&'a [Élément_2; 7]"),
        ("::root::Type", "Type"),
    ] {
        assert_eq!(render::short_type(qualified), expected);
    }
}

#[test]
fn unknown_bindings_do_not_create_edges_to_unrelated_pipes() {
    let pipes = roster::Schema::describe_pipes().collect::<Vec<_>>();
    let bindings = FixtureBinding
        .describe_bindings()
        .map(|binding| BindingDescription {
            name: "unrelated",
            ..binding
        })
        .collect::<Vec<_>>();
    for target in [DiagramTarget::MermaidFlowchart, DiagramTarget::GraphvizDot] {
        let rendered = render::render("Board", &pipes, Some(&bindings), target);
        assert!(!rendered.contains("installed as"));
        assert!(rendered.contains("unrelated"));
    }
    assert!(!html::render("Board", &pipes, Some(&bindings)).contains("<div class=\"physical\">"));
}

#[test]
fn semantic_graphs_do_not_invent_a_physical_installation() {
    let diagram = ProgramDiagram::<roster::Schema>::for_board::<Board>();
    for target in [DiagramTarget::MermaidFlowchart, DiagramTarget::GraphvizDot] {
        let rendered = diagram.render(target);
        assert!(rendered.contains("pipe0"));
        assert!(rendered.contains("pipe1"));
        assert!(rendered.contains("emits Out"));
        assert!(rendered.contains("receives In"));
        assert!(!rendered.contains("physical_scope"));
        assert!(!rendered.contains("binding0"));
        assert!(!rendered.contains("installed as"));
    }
}

#[test]
fn graph_documents_preserve_the_exact_target_syntax() {
    expect_test::expect![[r#"
        %% Experimental inspection prototype; not ready for application consumption.
        flowchart LR
          board["Board"]
          scope["Declared boundaries only; routes and reachability are runtime decisions"]
    "#]]
    .assert_eq(&render::render(
        "Board",
        &[],
        None,
        DiagramTarget::MermaidFlowchart,
    ));
    expect_test::expect![[r#"
        // Experimental inspection prototype; not ready for application consumption.
        digraph program {
          board [label="Board"];
          scope [label="Declared boundaries only; routes and reachability are runtime decisions"];
        }
    "#]]
    .assert_eq(&render::render(
        "Board",
        &[],
        None,
        DiagramTarget::GraphvizDot,
    ));
}

#[test]
fn text_snapshot_preserves_semantic_directions_and_physical_provenance() {
    let declaration = DeclarationLocation {
        package: "fixture",
        file: "src/program.rs",
        line: 7,
        column: 3,
    };
    let pipes = [PipeDescription {
        name: "client",
        documentation: &[" Sends commands. ", " Observes replies. "],
        protocol: "application::Controls",
        input: "application::Reply",
        output: "application::Command",
        declaration,
    }];
    let bindings = [BindingDescription {
        name: "client",
        documentation: &[" Owned bytes. "],
        binding: "transport::Carrier",
        driver: "transport::Queue",
        declaration: DeclarationLocation {
            line: 19,
            ..declaration
        },
    }];
    let rendered = render::render(
        "application::Board",
        &pipes,
        Some(&bindings),
        DiagramTarget::TextTree,
    );
    expect_test::expect![[r#"
        Experimental inspection prototype: development review only; not ready for application consumption.

        Program: Board
        Switchboard: routes messages between the named pipes below.

        Read directions from each pipe's perspective:
          emits (Out) -> switchboard -> receives (In)
        These are message families, not a request/reply ordering guarantee.

        client [Controls]
          Sends commands.
          Observes replies.
          emits to switchboard: Command
          receives from switchboard: Reply
          declared at: src/program.rs:7:3 (fixture)
          installed with: Queue
            Owned bytes.
          wired at: src/program.rs:19:3 (fixture)

        Scope: declared boundaries; runtime routes and reachability are not inferred.
        Transport occupancy, health, remote placement and compatibility are not measured here.
    "#]].assert_eq(&rendered);
    assert_eq!(
        rendered,
        render::render(
            "application::Board",
            &pipes,
            Some(&bindings),
            DiagramTarget::AnsiTextTree
        )
    );
}