use anyhow::Result;
use uni_db::{DataType, Uni};
#[tokio::test]
async fn test_path_variable() -> Result<()> {
let db = Uni::in_memory().build().await?;
db.schema()
.label("Person")
.property("name", DataType::String)
.edge_type("KNOWS", &["Person"], &["Person"])
.property("since", DataType::Int64)
.apply()
.await?;
let tx = db.session().tx().await?;
tx.execute("CREATE (a:Person {name: 'Alice'})").await?;
tx.execute("CREATE (b:Person {name: 'Bob'})").await?;
tx.execute("CREATE (c:Person {name: 'Charlie'})").await?;
tx.execute("MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'}) CREATE (a)-[:KNOWS {since: 2020}]->(b)").await?;
tx.execute("MATCH (b:Person {name: 'Bob'}), (c:Person {name: 'Charlie'}) CREATE (b)-[:KNOWS {since: 2021}]->(c)").await?;
tx.commit().await?;
let result = db.session().query("MATCH p = (a:Person {name: 'Alice'})-[:KNOWS*1..2]->(b) RETURN p, length(p) AS len ORDER BY len").await?;
assert_eq!(result.len(), 2);
let row1 = &result.rows()[0];
let len1: i64 = row1.get("len")?;
assert_eq!(len1, 1);
let row2 = &result.rows()[1];
let len2: i64 = row2.get("len")?;
assert_eq!(len2, 2);
let p1: uni_db::Path = row1.get("p")?;
assert_eq!(p1.nodes.len(), 2); assert_eq!(p1.edges.len(), 1);
let p2: uni_db::Path = row2.get("p")?;
assert_eq!(p2.nodes.len(), 3); assert_eq!(p2.edges.len(), 2);
let result = db.session().query("MATCH p = (a:Person {name: 'Alice'})-[:KNOWS]->(b) RETURN nodes(p) AS ns, relationships(p) AS rels").await?;
assert_eq!(result.len(), 1);
let row = &result.rows()[0];
let ns: Vec<uni_db::Node> = row.get("ns")?;
assert_eq!(ns.len(), 2);
let rels: Vec<uni_db::Edge> = row.get("rels")?;
assert_eq!(rels.len(), 1);
Ok(())
}
#[tokio::test]
async fn test_multihop_chained_path_variable() -> Result<()> {
let db = Uni::in_memory().build().await?;
db.schema()
.label("Person")
.property("name", DataType::String)
.edge_type("KNOWS", &["Person"], &["Person"])
.apply()
.await?;
let tx = db.session().tx().await?;
tx.execute("CREATE (a:Person {name: 'Alice'})").await?;
tx.execute("CREATE (b:Person {name: 'Bob'})").await?;
tx.execute("CREATE (c:Person {name: 'Charlie'})").await?;
tx.execute(
"MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'}) CREATE (a)-[:KNOWS]->(b)",
)
.await?;
tx.execute(
"MATCH (b:Person {name: 'Bob'}), (c:Person {name: 'Charlie'}) CREATE (b)-[:KNOWS]->(c)",
)
.await?;
tx.commit().await?;
let result = db.session().query(
"MATCH p = (a:Person {name: 'Alice'})-[r1:KNOWS]->(b:Person)-[r2:KNOWS]->(c:Person) RETURN p, a.name AS a_name, c.name AS c_name"
).await?;
assert_eq!(result.len(), 1, "Should return 1 path: Alice->Bob->Charlie");
let row = &result.rows()[0];
let a_name: String = row.get("a_name")?;
let c_name: String = row.get("c_name")?;
assert_eq!(a_name, "Alice");
assert_eq!(c_name, "Charlie");
let path: uni_db::Path = row.get("p")?;
assert_eq!(
path.nodes.len(),
3,
"Path should have 3 nodes: Alice, Bob, Charlie"
);
assert_eq!(path.edges.len(), 2, "Path should have 2 edges: r1, r2");
Ok(())
}