use langchainrust::{
AgentState, FunctionRouter, GraphBuilder, StateGraph, StateUpdate, END, START,
};
use std::collections::HashMap;
#[test]
fn test_visualize_ascii_linear_graph() {
let compiled = GraphBuilder::<AgentState>::new()
.add_node_fn("step1", |state| Ok(StateUpdate::full(state.clone())))
.add_node_fn("step2", |state| Ok(StateUpdate::full(state.clone())))
.add_edge(START, "step1")
.add_edge("step1", "step2")
.add_edge("step2", END)
.compile()
.unwrap();
let output = compiled.visualize_ascii();
println!("=== ASCII 输出 ===");
println!("{}", output);
assert!(output.contains("__start__"));
assert!(output.contains("step1"));
assert!(output.contains("step2"));
assert!(output.contains("__end__"));
}
#[test]
fn test_visualize_ascii_conditional_graph() {
let mut graph: StateGraph<AgentState> = StateGraph::new();
graph.add_node_fn("decision", |state| Ok(StateUpdate::full(state.clone())));
graph.add_node_fn("path_a", |state| Ok(StateUpdate::full(state.clone())));
graph.add_node_fn("path_b", |state| Ok(StateUpdate::full(state.clone())));
graph.add_edge(START, "decision");
graph.add_conditional_edges(
"decision",
"router",
HashMap::from([
("a".to_string(), "path_a".to_string()),
("b".to_string(), "path_b".to_string()),
]),
None,
);
graph.add_edge("path_a", END);
graph.add_edge("path_b", END);
let router = FunctionRouter::new(|_state| "a".to_string());
graph.set_conditional_router("router", router);
let compiled = graph.compile().unwrap();
let output = compiled.visualize_ascii();
println!("=== ASCII 条件图输出 ===");
println!("{}", output);
assert!(output.contains("Routers:"));
assert!(output.contains("router"));
assert!(output.contains("a → path_a"));
assert!(output.contains("b → path_b"));
}
#[test]
fn test_visualize_mermaid() {
let compiled = GraphBuilder::<AgentState>::new()
.add_node_fn("process", |state| Ok(StateUpdate::full(state.clone())))
.add_edge(START, "process")
.add_edge("process", END)
.compile()
.unwrap();
let output = compiled.visualize_mermaid();
println!("=== Mermaid 输出 ===");
println!("{}", output);
assert!(output.contains("```mermaid"));
assert!(output.contains("graph TD"));
assert!(output.contains("__start__"));
assert!(output.contains("__end__"));
assert!(output.contains("process"));
}
#[test]
fn test_visualize_json() {
let compiled = GraphBuilder::<AgentState>::new()
.add_node_fn("node1", |state| Ok(StateUpdate::full(state.clone())))
.add_node_fn("node2", |state| Ok(StateUpdate::full(state.clone())))
.add_edge(START, "node1")
.add_edge("node1", "node2")
.add_edge("node2", END)
.compile()
.unwrap();
let json = compiled.visualize_json();
println!("=== JSON 输出 ===");
println!("{}", serde_json::to_string_pretty(&json).unwrap());
assert!(json["entry_point"].is_string());
assert!(json["nodes"].is_array());
assert!(json["edges"].is_array());
assert!(json["recursion_limit"].is_number());
let nodes = json["nodes"].as_array().unwrap();
assert_eq!(nodes.len(), 2);
}