use anyhow::Result;
use uni_db::{Uni, Value};
#[tokio::test]
async fn test_match_returns_node_type() -> Result<()> {
let db = Uni::temporary().build().await?;
let tx = db.session().tx().await?;
tx.execute("CREATE LABEL Person (name STRING, age INT32)")
.await?;
tx.execute("CREATE (:Person {name: 'Alice', age: 30})")
.await?;
tx.execute("CREATE (:Person {name: 'Bob', age: 25})")
.await?;
tx.commit().await?;
db.flush().await?;
let results = db
.session()
.query("MATCH (n:Person) RETURN n ORDER BY n.name")
.await?;
assert_eq!(results.len(), 2, "Expected 2 results");
let node1 = results.rows()[0].value("n").unwrap();
match node1 {
Value::Node(node) => {
assert_eq!(node.labels, &["Person".to_string()]);
assert_eq!(
node.properties.get("name"),
Some(&Value::String("Alice".to_string()))
);
assert_eq!(node.properties.get("age"), Some(&Value::Int(30)));
assert!(!node.properties.contains_key("_vid"));
assert!(!node.properties.contains_key("_labels"));
}
other => panic!("Expected Value::Node, got {:?}", other),
}
let node2 = results.rows()[1].value("n").unwrap();
match node2 {
Value::Node(node) => {
assert_eq!(node.labels, &["Person".to_string()]);
assert_eq!(
node.properties.get("name"),
Some(&Value::String("Bob".to_string()))
);
assert_eq!(node.properties.get("age"), Some(&Value::Int(25)));
}
other => panic!("Expected Value::Node, got {:?}", other),
}
Ok(())
}
#[tokio::test]
async fn test_match_with_edge_returns_proper_types() -> Result<()> {
let db = Uni::temporary().build().await?;
let tx = db.session().tx().await?;
tx.execute("CREATE LABEL Person (name STRING)").await?;
tx.execute("CREATE EDGE TYPE KNOWS () FROM Person TO Person")
.await?;
tx.execute("CREATE (a:Person {name: 'Alice'})").await?;
tx.execute("CREATE (b:Person {name: 'Bob'})").await?;
tx.execute(
"MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'}) CREATE (a)-[:KNOWS]->(b)",
)
.await?;
tx.commit().await?;
db.flush().await?;
let results = db
.session()
.query("MATCH (a:Person)-[r:KNOWS]->(b:Person) RETURN a, r, b")
.await?;
assert_eq!(results.len(), 1, "Expected 1 result");
let row = &results.rows()[0];
match row.value("a").unwrap() {
Value::Node(node) => {
assert_eq!(node.labels, &["Person".to_string()]);
assert_eq!(
node.properties.get("name"),
Some(&Value::String("Alice".to_string()))
);
}
other => panic!("Expected Value::Node for 'a', got {:?}", other),
}
match row.value("r").unwrap() {
Value::Edge(edge) => {
assert_eq!(edge.edge_type, "KNOWS");
assert!(!edge.properties.contains_key("_eid"));
assert!(!edge.properties.contains_key("_type"));
}
other => panic!("Expected Value::Edge for 'r', got {:?}", other),
}
match row.value("b").unwrap() {
Value::Node(node) => {
assert_eq!(node.labels, &["Person".to_string()]);
assert_eq!(
node.properties.get("name"),
Some(&Value::String("Bob".to_string()))
);
}
other => panic!("Expected Value::Node for 'b', got {:?}", other),
}
Ok(())
}
#[tokio::test]
async fn test_property_access_still_works() -> Result<()> {
let db = Uni::temporary().build().await?;
let tx = db.session().tx().await?;
tx.execute("CREATE LABEL Person (name STRING, age INT32)")
.await?;
tx.execute("CREATE (:Person {name: 'Alice', age: 30})")
.await?;
tx.commit().await?;
db.flush().await?;
let results = db
.session()
.query("MATCH (n:Person) RETURN n.name AS name, n.age AS age")
.await?;
assert_eq!(results.len(), 1);
let row = &results.rows()[0];
assert_eq!(row.value("name"), Some(&Value::String("Alice".to_string())));
assert_eq!(row.value("age"), Some(&Value::Int(30)));
Ok(())
}