#![allow(unused_variables)]
use interstellar::storage::Graph;
use interstellar::traversal::__;
use interstellar::value::{Value, VertexId};
use std::collections::HashMap;
fn create_basic_graph() -> Graph {
let graph = Graph::new();
let mut props = HashMap::new();
props.insert("name".to_string(), Value::String("Alice".to_string()));
props.insert("age".to_string(), Value::Int(30));
graph.add_vertex("person", props);
let mut props = HashMap::new();
props.insert("name".to_string(), Value::String("Bob".to_string()));
props.insert("age".to_string(), Value::Int(25));
graph.add_vertex("person", props);
graph
}
fn create_graph_with_edges() -> Graph {
let graph = Graph::new();
let mut props = HashMap::new();
props.insert("name".to_string(), Value::String("Alice".to_string()));
graph.add_vertex("person", props);
let mut props = HashMap::new();
props.insert("name".to_string(), Value::String("Bob".to_string()));
graph.add_vertex("person", props);
let mut props = HashMap::new();
props.insert("name".to_string(), Value::String("Charlie".to_string()));
graph.add_vertex("person", props);
let mut props = HashMap::new();
props.insert("since".to_string(), Value::Int(2020));
graph
.add_edge(VertexId(0), VertexId(1), "knows", props)
.unwrap();
let mut props = HashMap::new();
props.insert("since".to_string(), Value::Int(2021));
graph
.add_edge(VertexId(0), VertexId(2), "knows", props)
.unwrap();
let mut props = HashMap::new();
props.insert("since".to_string(), Value::Int(2020));
graph
.add_edge(VertexId(1), VertexId(2), "knows", props)
.unwrap();
graph
}
mod group_key_constructors {
use super::*;
use interstellar::traversal::aggregate::{GroupKey, GroupValue};
#[test]
fn group_key_by_label() {
let key = GroupKey::by_label();
assert!(matches!(key, GroupKey::Label));
}
#[test]
fn group_key_by_property() {
let key = GroupKey::by_property("age");
if let GroupKey::Property(prop) = key {
assert_eq!(prop, "age");
} else {
panic!("Expected Property key");
}
}
#[test]
fn group_key_by_traversal() {
let t = __.values("name");
let key = GroupKey::by_traversal(t);
assert!(matches!(key, GroupKey::Traversal(_)));
}
#[test]
fn group_value_identity() {
let value = GroupValue::identity();
assert!(matches!(value, GroupValue::Identity));
}
#[test]
fn group_value_by_property() {
let value = GroupValue::by_property("name");
if let GroupValue::Property(prop) = value {
assert_eq!(prop, "name");
} else {
panic!("Expected Property value");
}
}
#[test]
fn group_value_by_traversal() {
let t = __.values("name");
let value = GroupValue::by_traversal(t);
assert!(matches!(value, GroupValue::Traversal(_)));
}
}
mod group_step_key_types {
use super::*;
#[test]
fn group_by_bool_property() {
let graph = Graph::new();
let mut props = HashMap::new();
props.insert("active".to_string(), Value::Bool(true));
graph.add_vertex("user", props);
let mut props = HashMap::new();
props.insert("active".to_string(), Value::Bool(false));
graph.add_vertex("user", props);
let mut props = HashMap::new();
props.insert("active".to_string(), Value::Bool(true));
graph.add_vertex("user", props);
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let result = g
.v()
.has_label("user")
.group()
.by_key("active")
.by_value()
.build()
.next();
assert!(result.is_some());
if let Some(Value::Map(map)) = result {
assert!(map.contains_key("true") || map.contains_key("false"));
}
}
#[test]
fn group_by_float_property() {
let graph = Graph::new();
let mut props = HashMap::new();
props.insert("score".to_string(), Value::Float(0.5));
graph.add_vertex("item", props);
let mut props = HashMap::new();
props.insert("score".to_string(), Value::Float(0.5));
graph.add_vertex("item", props);
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let result = g
.v()
.has_label("item")
.group()
.by_key("score")
.by_value()
.build()
.next();
assert!(result.is_some());
if let Some(Value::Map(map)) = result {
assert!(map.contains_key("0.5"));
}
}
#[test]
fn group_by_null_property() {
let graph = Graph::new();
let mut props = HashMap::new();
props.insert("value".to_string(), Value::Null);
graph.add_vertex("item", props);
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let result = g
.v()
.has_label("item")
.group()
.by_key("value")
.by_value()
.build()
.next();
assert!(result.is_some());
if let Some(Value::Map(map)) = result {
assert!(map.contains_key("null"));
}
}
}
mod group_count_key_types {
use super::*;
#[test]
fn group_count_by_bool_property() {
let graph = Graph::new();
let mut props = HashMap::new();
props.insert("active".to_string(), Value::Bool(true));
graph.add_vertex("user", props);
let mut props = HashMap::new();
props.insert("active".to_string(), Value::Bool(false));
graph.add_vertex("user", props);
let mut props = HashMap::new();
props.insert("active".to_string(), Value::Bool(true));
graph.add_vertex("user", props);
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let result = g
.v()
.has_label("user")
.group_count()
.by_key("active")
.build()
.next();
assert!(result.is_some());
if let Some(Value::Map(map)) = result {
assert_eq!(map.get("true"), Some(&Value::Int(2)));
assert_eq!(map.get("false"), Some(&Value::Int(1)));
}
}
#[test]
fn group_count_by_vertex_reference() {
let graph = create_graph_with_edges();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let result = g.e().group_count().by_traversal(__.in_v()).build().next();
assert!(result.is_some());
if let Some(Value::Map(map)) = result {
assert!(map.keys().any(|k| k.starts_with("v[")));
}
}
#[test]
fn group_count_by_edge_reference() {
let graph = create_graph_with_edges();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let result = g.e().group_count().by_label().build().next();
assert!(result.is_some());
if let Some(Value::Map(map)) = result {
assert!(map.contains_key("knows"));
}
}
}
mod group_value_traversal_tests {
use super::*;
#[test]
fn group_value_traversal_multiple_results() {
let graph = create_graph_with_edges();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let result = g
.v()
.has_label("person")
.group()
.by_label()
.by_value_traversal(__.out().values("name"))
.build()
.next();
assert!(result.is_some());
if let Some(Value::Map(map)) = result {
assert!(map.contains_key("person"));
if let Some(Value::List(values)) = map.get("person") {
assert!(!values.is_empty());
}
}
}
#[test]
fn group_value_traversal_empty_results() {
let graph = Graph::new();
let mut props = HashMap::new();
props.insert("name".to_string(), Value::String("Isolated".to_string()));
graph.add_vertex("person", props);
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let result = g
.v()
.has_label("person")
.group()
.by_label()
.by_value_traversal(__.out().values("name"))
.build()
.next();
assert!(result.is_some());
if let Some(Value::Map(map)) = result {
if let Some(Value::List(values)) = map.get("person") {
assert!(values.is_empty());
}
}
}
#[test]
fn group_value_traversal_single_result() {
let graph = Graph::new();
let mut props = HashMap::new();
props.insert("name".to_string(), Value::String("Alice".to_string()));
graph.add_vertex("person", props);
let mut props = HashMap::new();
props.insert("name".to_string(), Value::String("Bob".to_string()));
graph.add_vertex("person", props);
graph
.add_edge(VertexId(0), VertexId(1), "knows", HashMap::new())
.unwrap();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let result = g
.v()
.has_label("person")
.group()
.by_key("name")
.by_value_traversal(__.out().values("name"))
.build()
.next();
assert!(result.is_some());
if let Some(Value::Map(map)) = result {
if let Some(Value::List(values)) = map.get("Alice") {
assert!(!values.is_empty());
}
}
}
}
mod non_element_input_tests {
use super::*;
#[test]
fn group_non_vertex_non_edge_by_label() {
let graph = Graph::new();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let result = g
.inject([Value::Int(1), Value::Int(2), Value::Int(3)])
.group()
.by_label()
.by_value()
.build()
.next();
assert!(result.is_some());
if let Some(Value::Map(map)) = result {
assert!(map.is_empty());
}
}
#[test]
fn group_count_non_vertex_non_edge_by_property() {
let graph = Graph::new();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let result = g
.inject([
Value::String("a".to_string()),
Value::String("b".to_string()),
])
.group_count()
.by_key("nonexistent")
.build()
.next();
assert!(result.is_some());
if let Some(Value::Map(map)) = result {
assert!(map.is_empty());
}
}
}
mod default_selector_tests {
use super::*;
#[test]
fn group_step_default_key_is_label() {
let graph = create_basic_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let result = g.v().group().build().next();
assert!(result.is_some());
if let Some(Value::Map(map)) = result {
assert!(map.contains_key("person"));
}
}
#[test]
fn group_step_default_value_is_identity() {
let graph = create_basic_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let result = g.v().group().by_label().build().next();
assert!(result.is_some());
if let Some(Value::Map(map)) = result {
if let Some(Value::List(values)) = map.get("person") {
for v in values {
assert!(matches!(v, Value::Vertex(_)));
}
}
}
}
#[test]
fn group_count_step_default_is_label() {
let graph = create_basic_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let result = g.v().group_count().build().next();
assert!(result.is_some());
if let Some(Value::Map(map)) = result {
assert!(map.contains_key("person"));
assert_eq!(map.get("person"), Some(&Value::Int(2)));
}
}
}
mod path_preservation_tests {
use super::*;
#[test]
fn group_preserves_last_path() {
let graph = create_basic_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let result = g
.v()
.with_path()
.as_("start")
.group()
.by_label()
.by_value()
.build()
.next();
assert!(result.is_some());
}
#[test]
fn group_count_preserves_last_path() {
let graph = create_basic_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let result = g
.v()
.with_path()
.as_("start")
.group_count()
.by_label()
.build()
.next();
assert!(result.is_some());
}
}