#![allow(unused_variables)]
use interstellar::storage::Graph;
use interstellar::value::{EdgeId, Value, VertexId};
use std::collections::HashMap;
fn create_test_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));
props.insert("city".to_string(), Value::String("NYC".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_vertex("empty", HashMap::new());
let mut props = HashMap::new();
props.insert("weight".to_string(), Value::Float(0.5));
props.insert("since".to_string(), Value::Int(2020));
graph
.add_edge(VertexId(0), VertexId(1), "knows", props)
.unwrap();
graph
.add_edge(VertexId(1), VertexId(2), "knows", HashMap::new())
.unwrap();
graph
}
mod properties_step_tests {
use super::*;
#[test]
fn properties_extracts_all_vertex_properties() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g.v_ids([VertexId(0)]).properties().to_list();
assert_eq!(results.len(), 3);
for result in &results {
if let Value::Map(map) = result {
assert!(map.contains_key("key"));
assert!(map.contains_key("value"));
} else {
panic!("Expected Map for property");
}
}
}
#[test]
fn properties_extracts_specific_keys() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g.v_ids([VertexId(0)]).properties_keys(["name"]).to_list();
assert_eq!(results.len(), 1);
if let Value::Map(map) = &results[0] {
assert_eq!(map.get("key"), Some(&Value::String("name".to_string())));
assert_eq!(map.get("value"), Some(&Value::String("Alice".to_string())));
}
}
#[test]
fn properties_handles_empty_vertex() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g.v_ids([VertexId(2)]).properties().to_list();
assert!(results.is_empty());
}
#[test]
fn properties_handles_edge() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g.e_ids([EdgeId(0)]).properties().to_list();
assert_eq!(results.len(), 2); }
#[test]
fn properties_handles_edge_without_properties() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g.e_ids([EdgeId(1)]).properties().to_list();
assert!(results.is_empty());
}
#[test]
fn properties_ignores_non_elements() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g
.inject([Value::Int(42), Value::String("hello".to_string())])
.properties()
.to_list();
assert!(results.is_empty());
}
#[test]
fn properties_with_nonexistent_key() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g
.v_ids([VertexId(0)])
.properties_keys(["nonexistent"])
.to_list();
assert!(results.is_empty());
}
}
mod value_map_step_tests {
use super::*;
#[test]
fn value_map_extracts_all_properties() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g.v_ids([VertexId(0)]).value_map().to_list();
assert_eq!(results.len(), 1);
if let Value::Map(map) = &results[0] {
assert!(map.contains_key("name"));
assert!(map.contains_key("age"));
assert!(map.contains_key("city"));
}
}
#[test]
fn value_map_with_specific_keys() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g
.v_ids([VertexId(0)])
.value_map_keys(["name", "age"])
.to_list();
assert_eq!(results.len(), 1);
if let Value::Map(map) = &results[0] {
assert!(map.contains_key("name"));
assert!(map.contains_key("age"));
assert!(!map.contains_key("city"));
}
}
#[test]
fn value_map_empty_properties() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g
.v_ids([VertexId(2)]) .value_map()
.to_list();
assert_eq!(results.len(), 1);
if let Value::Map(map) = &results[0] {
assert!(map.is_empty());
}
}
#[test]
fn value_map_edge() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g.e_ids([EdgeId(0)]).value_map().to_list();
assert_eq!(results.len(), 1);
if let Value::Map(map) = &results[0] {
assert!(map.contains_key("weight"));
assert!(map.contains_key("since"));
}
}
#[test]
fn value_map_ignores_non_elements() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g.inject([Value::Int(42)]).value_map().to_list();
assert_eq!(results.len(), 1);
if let Value::Map(map) = &results[0] {
assert!(map.is_empty());
} else {
panic!("Expected Value::Map");
}
}
}
mod element_map_step_tests {
use super::*;
#[test]
fn element_map_includes_id_and_label() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g.v_ids([VertexId(0)]).element_map().to_list();
assert_eq!(results.len(), 1);
if let Value::Map(map) = &results[0] {
assert!(map.contains_key("id"));
assert!(map.contains_key("label"));
assert!(map.contains_key("name"));
assert!(map.contains_key("age"));
}
}
#[test]
fn element_map_with_specific_keys() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g.v_ids([VertexId(0)]).element_map_keys(["name"]).to_list();
assert_eq!(results.len(), 1);
if let Value::Map(map) = &results[0] {
assert!(map.contains_key("id"));
assert!(map.contains_key("label"));
assert!(map.contains_key("name"));
assert!(!map.contains_key("age"));
}
}
#[test]
fn element_map_edge_includes_endpoints() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g.e_ids([EdgeId(0)]).element_map().to_list();
assert_eq!(results.len(), 1);
if let Value::Map(map) = &results[0] {
assert!(map.contains_key("id"));
assert!(map.contains_key("label"));
assert!(map.contains_key("IN"));
assert!(map.contains_key("OUT"));
assert!(map.contains_key("weight"));
}
}
#[test]
fn element_map_empty_vertex() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g.v_ids([VertexId(2)]).element_map().to_list();
assert_eq!(results.len(), 1);
if let Value::Map(map) = &results[0] {
assert!(map.contains_key("id"));
assert!(map.contains_key("label"));
assert_eq!(map.len(), 2);
}
}
#[test]
fn element_map_ignores_non_elements() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g
.inject([Value::String("test".to_string())])
.element_map()
.to_list();
assert_eq!(results.len(), 1);
if let Value::Map(map) = &results[0] {
assert!(map.is_empty());
} else {
panic!("Expected Value::Map");
}
}
}
mod property_map_step_tests {
use super::*;
#[test]
fn property_map_wraps_values_in_lists() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g.v_ids([VertexId(0)]).property_map().to_list();
assert_eq!(results.len(), 1);
if let Value::Map(map) = &results[0] {
for (_key, value) in map.iter() {
assert!(matches!(value, Value::List(_)));
}
}
}
#[test]
fn property_map_with_specific_keys() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g.v_ids([VertexId(0)]).property_map_keys(["name"]).to_list();
assert_eq!(results.len(), 1);
if let Value::Map(map) = &results[0] {
assert!(map.contains_key("name"));
assert!(!map.contains_key("age"));
}
}
#[test]
fn property_map_empty_vertex() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g.v_ids([VertexId(2)]).property_map().to_list();
assert_eq!(results.len(), 1);
if let Value::Map(map) = &results[0] {
assert!(map.is_empty());
}
}
#[test]
fn property_map_edge() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g.e_ids([EdgeId(0)]).property_map().to_list();
assert_eq!(results.len(), 1);
if let Value::Map(map) = &results[0] {
assert!(map.contains_key("weight"));
if let Some(Value::List(weights)) = map.get("weight") {
assert!(!weights.is_empty());
}
}
}
#[test]
fn property_map_ignores_non_elements() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g.inject([Value::Int(42)]).property_map().to_list();
assert_eq!(results.len(), 1);
if let Value::Map(map) = &results[0] {
assert!(map.is_empty());
} else {
panic!("Expected Value::Map");
}
}
}
mod path_preservation_tests {
use super::*;
#[test]
fn properties_preserves_path() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g
.v_ids([VertexId(0)])
.with_path()
.as_("start")
.properties()
.to_list();
assert!(!results.is_empty());
}
#[test]
fn value_map_preserves_path() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let g = snapshot.gremlin();
let results: Vec<Value> = g
.v_ids([VertexId(0)])
.with_path()
.as_("start")
.value_map()
.to_list();
assert_eq!(results.len(), 1);
}
}
mod bulk_preservation_tests {
use super::*;
use interstellar::traversal::step::Step;
use interstellar::traversal::transform::PropertiesStep;
use interstellar::traversal::{ExecutionContext, SnapshotLike, Traverser};
#[test]
fn properties_step_expands_bulk() {
let graph = create_test_graph();
let snapshot = graph.snapshot();
let ctx = ExecutionContext::new(snapshot.storage(), snapshot.interner());
let step = PropertiesStep::new();
let mut traverser = Traverser::from_vertex(VertexId(0));
traverser.bulk = 5;
let input = vec![traverser];
let output: Vec<Traverser> = step.apply(&ctx, Box::new(input.into_iter())).collect();
assert_eq!(output.len(), 3); for t in output {
assert_eq!(t.bulk, 5);
}
}
}
mod step_name_tests {
use interstellar::traversal::step::Step;
use interstellar::traversal::transform::{
ElementMapStep, PropertiesStep, PropertyMapStep, ValueMapStep,
};
#[test]
fn properties_step_name() {
let step = PropertiesStep::new();
assert_eq!(step.name(), "properties");
}
#[test]
fn value_map_step_name() {
let step = ValueMapStep::new();
assert_eq!(step.name(), "valueMap");
}
#[test]
fn element_map_step_name() {
let step = ElementMapStep::new();
assert_eq!(step.name(), "elementMap");
}
#[test]
fn property_map_step_name() {
let step = PropertyMapStep::new();
assert_eq!(step.name(), "propertyMap");
}
}
mod from_keys_tests {
use interstellar::traversal::step::Step;
use interstellar::traversal::transform::PropertiesStep;
#[test]
fn properties_from_keys_iterator() {
let keys = vec!["name", "age"];
let step = PropertiesStep::from_keys(keys);
assert_eq!(step.name(), "properties");
}
#[test]
fn properties_from_keys_array() {
let step = PropertiesStep::from_keys(["name", "age"]);
assert_eq!(step.name(), "properties");
}
}