#![allow(unused_variables)]
use interstellar::p;
use interstellar::traversal::__;
use interstellar::value::Value;
use crate::common::graphs::create_small_graph;
#[test]
fn has_label_filters_vertices_by_label() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let people = g.v().has_label("person").to_list();
assert_eq!(people.len(), 3);
let software = g.v().has_label("software").to_list();
assert_eq!(software.len(), 1); }
#[test]
fn has_label_filters_edges_by_label() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let knows_edges = g.e().has_label("knows").to_list();
assert_eq!(knows_edges.len(), 3);
let uses_edges = g.e().has_label("uses").to_list();
assert_eq!(uses_edges.len(), 2);
}
#[test]
fn has_label_any_filters_by_multiple_labels() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let all = g.v().has_label_any(["person", "software"]).to_list();
assert_eq!(all.len(), 4);
}
#[test]
fn has_label_returns_empty_for_nonexistent_label() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().has_label("unknown").to_list();
assert!(results.is_empty());
}
#[test]
fn has_filters_by_property_existence() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let with_name = g.v().has("name").to_list();
assert_eq!(with_name.len(), 4);
let with_age = g.v().has("age").to_list();
assert_eq!(with_age.len(), 3);
let with_version = g.v().has("version").to_list();
assert_eq!(with_version.len(), 1);
}
#[test]
fn has_value_filters_by_property_value() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let alice = g.v().has_value("name", "Alice").to_list();
assert_eq!(alice.len(), 1);
let age_30 = g.v().has_value("age", 30i64).to_list();
assert_eq!(age_30.len(), 1);
}
#[test]
fn has_id_filters_vertices_by_id() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let result = g.v().has_id(tg.alice).to_list();
assert_eq!(result.len(), 1);
assert_eq!(result[0].as_vertex_id(), Some(tg.alice));
}
#[test]
fn has_ids_filters_by_multiple_ids() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().has_ids([tg.alice, tg.bob, tg.charlie]).to_list();
assert_eq!(results.len(), 3);
}
#[test]
fn filter_with_custom_predicate() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let positives = g
.inject([1i64, -2i64, 3i64, -4i64])
.filter(|_ctx, v| matches!(v, Value::Int(n) if *n > 0))
.to_list();
assert_eq!(positives.len(), 2);
assert_eq!(positives[0], Value::Int(1));
assert_eq!(positives[1], Value::Int(3));
}
#[test]
fn dedup_removes_duplicates() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.inject([1i64, 2i64, 1i64, 3i64, 2i64]).dedup().to_list();
assert_eq!(results.len(), 3);
}
#[test]
fn limit_restricts_result_count() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().limit(2).to_list();
assert_eq!(results.len(), 2);
}
#[test]
fn limit_with_more_than_available() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().limit(100).to_list();
assert_eq!(results.len(), 4);
}
#[test]
fn skip_skips_elements() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.inject([1i64, 2i64, 3i64, 4i64, 5i64]).skip(2).to_list();
assert_eq!(results.len(), 3);
assert_eq!(results[0], Value::Int(3));
}
#[test]
fn range_selects_range_of_elements() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.inject([0i64, 1i64, 2i64, 3i64, 4i64, 5i64])
.range(2, 5)
.to_list();
assert_eq!(results.len(), 3);
assert_eq!(results[0], Value::Int(2));
assert_eq!(results[1], Value::Int(3));
assert_eq!(results[2], Value::Int(4));
}
#[test]
fn chained_filters() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().has_label("person").has("age").to_list();
assert_eq!(results.len(), 3);
}
#[test]
fn test_tail_with_order() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.has_label("person")
.values("age")
.order()
.build()
.tail_n(2)
.to_list();
assert_eq!(results.len(), 2);
assert_eq!(results[0], Value::Int(30));
assert_eq!(results[1], Value::Int(35));
}
#[test]
fn test_tail_single_element() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.has_label("person")
.values("age")
.order()
.build()
.tail()
.to_list();
assert_eq!(results.len(), 1);
assert_eq!(results[0], Value::Int(35)); }
#[test]
fn test_tail_chained_with_navigation() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().has_id(tg.alice).out_e().tail_n(2).to_list();
assert_eq!(results.len(), 2);
}
#[test]
fn test_dedup_by_key_with_navigation() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.has_id(tg.alice)
.out_labels(&["knows"])
.dedup_by_label()
.to_list();
assert_eq!(results.len(), 1);
}
#[test]
fn test_dedup_by_traversal_with_values() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.has_label("person")
.dedup_by(__.values("age"))
.to_list();
assert_eq!(results.len(), 3);
}
#[test]
fn test_coin_zero_filters_all() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().coin(0.0).to_list();
assert!(results.is_empty());
}
#[test]
fn test_coin_one_passes_all() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let all_vertices = g.v().to_list();
let coin_results = g.v().coin(1.0).to_list();
assert_eq!(coin_results.len(), all_vertices.len());
}
#[test]
fn test_coin_with_filter_chain() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().has_label("person").coin(1.0).to_list();
assert_eq!(results.len(), 3); }
#[test]
fn test_sample_respects_limit() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().sample(2).to_list();
assert_eq!(results.len(), 2);
}
#[test]
fn test_sample_with_fewer_elements() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().has_label("person").sample(10).to_list();
assert_eq!(results.len(), 3);
}
#[test]
fn test_sample_chained_with_navigation() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.e().sample(2).to_list();
assert_eq!(results.len(), 2);
}
#[test]
fn test_has_key_on_properties() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().has_id(tg.alice).properties().has_key("age").to_list();
assert_eq!(results.len(), 1);
}
#[test]
fn test_has_key_any_on_properties() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.has_id(tg.alice)
.properties()
.has_key_any(["name", "age"])
.to_list();
assert_eq!(results.len(), 2);
}
#[test]
fn test_has_prop_value_on_properties() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.has_label("person")
.properties()
.has_prop_value("Alice")
.to_list();
assert_eq!(results.len(), 1);
}
#[test]
fn test_where_p_with_comparison() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.has_label("person")
.values("age")
.where_p(p::gt(25))
.to_list();
assert_eq!(results.len(), 2); assert!(results.contains(&Value::Int(30)));
assert!(results.contains(&Value::Int(35)));
}
#[test]
fn test_where_p_with_within() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.has_label("person")
.values("age")
.where_p(p::within([25, 35]))
.to_list();
assert_eq!(results.len(), 2); assert!(results.contains(&Value::Int(25)));
assert!(results.contains(&Value::Int(35)));
}
#[test]
fn test_where_p_with_between() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.has_label("person")
.values("age")
.where_p(p::between(25, 35))
.to_list();
assert_eq!(results.len(), 2); assert!(results.contains(&Value::Int(25)));
assert!(results.contains(&Value::Int(30)));
}
#[test]
fn test_where_p_combined_with_and() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.has_label("person")
.values("age")
.where_p(p::and(p::gte(25), p::lte(30)))
.to_list();
assert_eq!(results.len(), 2); assert!(results.contains(&Value::Int(25)));
assert!(results.contains(&Value::Int(30)));
}
#[test]
fn test_chain_dedup_tail() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.has_id(tg.alice)
.out_labels(&["knows"])
.out_labels(&["knows"])
.dedup()
.tail()
.to_list();
assert!(results.len() <= 1);
}
#[test]
fn test_chain_sample_where_p() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.has_label("person")
.sample(10)
.values("age")
.where_p(p::gt(25))
.to_list();
assert_eq!(results.len(), 2); }
#[test]
fn test_chain_order_tail_where_p() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.has_label("person")
.values("age")
.order()
.build()
.tail_n(2)
.where_p(p::gte(30))
.to_list();
assert_eq!(results.len(), 2);
assert!(results.contains(&Value::Int(30)));
assert!(results.contains(&Value::Int(35)));
}
#[test]
fn test_anonymous_traversal_tail() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.inject([1i64, 2i64, 3i64, 4i64, 5i64]).tail_n(2).to_list();
assert_eq!(results.len(), 2);
assert_eq!(results[0], Value::Int(4));
assert_eq!(results[1], Value::Int(5));
}
#[test]
fn test_anonymous_traversal_sample() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.inject([1i64, 2i64, 3i64, 4i64, 5i64]).sample(2).to_list();
assert_eq!(results.len(), 2);
}
#[test]
fn test_anonymous_traversal_where_p() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.inject([10i64, 20i64, 30i64, 40i64, 50i64])
.local(__.where_p(p::gt(25)))
.to_list();
assert_eq!(results.len(), 3);
}
#[test]
fn test_full_pipeline_with_new_steps() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.has_label("person")
.out_labels(&["knows"])
.dedup()
.values("age")
.where_p(p::gt(20))
.tail_n(2)
.to_list();
assert!(results.len() <= 2);
}
#[test]
fn where_filters_by_sub_traversal_existence() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().where_(__.out()).to_list();
assert_eq!(results.len(), 3); }
#[test]
fn where_filters_by_labeled_edges() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().where_(__.out_labels(&["knows"])).to_list();
assert_eq!(results.len(), 3);
for v in &results {
let id = v.as_vertex_id().unwrap();
assert!(id == tg.alice || id == tg.bob || id == tg.charlie);
}
}
#[test]
fn where_filters_by_chained_sub_traversal() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.where_(__.out_labels(&["knows"]).out_labels(&["uses"]))
.to_list();
assert_eq!(results.len(), 2); }
#[test]
fn where_empty_sub_traversal_filters_out() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().where_(__.out_labels(&["nonexistent"])).to_list();
assert!(results.is_empty());
}
#[test]
fn not_filters_to_traversers_without_outgoing_edges() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().not(__.out()).to_list();
assert_eq!(results.len(), 1);
assert_eq!(results[0].as_vertex_id(), Some(tg.graphdb));
}
#[test]
fn not_is_inverse_of_where() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let with_out = g.v().where_(__.out()).to_list();
let without_out = g.v().not(__.out()).to_list();
assert_eq!(with_out.len() + without_out.len(), 4);
let with_ids: Vec<_> = with_out.iter().filter_map(|v| v.as_vertex_id()).collect();
let without_ids: Vec<_> = without_out
.iter()
.filter_map(|v| v.as_vertex_id())
.collect();
for id in &with_ids {
assert!(!without_ids.contains(id));
}
}
#[test]
fn not_filters_by_labeled_edges() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().not(__.out_labels(&["uses"])).to_list();
assert_eq!(results.len(), 2);
let ids: Vec<_> = results.iter().filter_map(|v| v.as_vertex_id()).collect();
assert!(ids.contains(&tg.charlie));
assert!(ids.contains(&tg.graphdb));
}
#[test]
fn not_with_has_label_sub_traversal() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().not(__.has_label("person")).to_list();
assert_eq!(results.len(), 1);
assert_eq!(results[0].as_vertex_id(), Some(tg.graphdb));
}
#[test]
fn not_finds_leaf_vertices() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let leaves = g.v().not(__.out()).to_list();
assert_eq!(leaves.len(), 1);
let leaf = &leaves[0];
assert!(leaf.is_vertex());
assert_eq!(leaf.as_vertex_id(), Some(tg.graphdb));
}
#[test]
fn and_requires_all_conditions() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().and_(vec![__.out(), __.in_()]).to_list();
assert_eq!(results.len(), 3); }
#[test]
fn and_short_circuits_on_first_failure() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.and_(vec![__.out_labels(&["knows"]), __.out_labels(&["uses"])])
.to_list();
assert_eq!(results.len(), 2);
let ids: Vec<_> = results.iter().filter_map(|v| v.as_vertex_id()).collect();
assert!(ids.contains(&tg.alice));
assert!(ids.contains(&tg.bob));
}
#[test]
fn and_with_empty_vec_passes_all() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().and_(vec![]).to_list();
assert_eq!(results.len(), 4);
}
#[test]
fn or_accepts_any_condition() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.or_(vec![__.out_labels(&["knows"]), __.out_labels(&["uses"])])
.to_list();
assert_eq!(results.len(), 3); }
#[test]
fn or_short_circuits_on_first_success() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.or_(vec![__.has_label("person"), __.has_label("software")])
.to_list();
assert_eq!(results.len(), 4); }
#[test]
fn or_with_empty_vec_filters_all() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g.v().or_(vec![]).to_list();
assert!(results.is_empty());
}
#[test]
fn or_finds_vertices_with_either_edge_type() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.or_(vec![__.out_labels(&["uses"]), __.in_labels(&["uses"])])
.to_list();
assert_eq!(results.len(), 3);
let ids: Vec<_> = results.iter().filter_map(|v| v.as_vertex_id()).collect();
assert!(ids.contains(&tg.alice));
assert!(ids.contains(&tg.bob));
assert!(ids.contains(&tg.graphdb));
}
#[test]
fn where_and_not_combined() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.has_label("person")
.not(__.out_labels(&["uses"]))
.to_list();
assert_eq!(results.len(), 1); assert_eq!(results[0].as_vertex_id(), Some(tg.charlie));
}
#[test]
fn nested_filter_steps() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let results = g
.v()
.where_(__.out_labels(&["knows"]).out_labels(&["knows"]))
.to_list();
assert_eq!(results.len(), 3);
}
#[test]
fn anonymous_where_factory() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let anon = __.where_(__.out());
let results = g.v().append(anon).to_list();
assert_eq!(results.len(), 3);
}
#[test]
fn anonymous_not_factory() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let anon = __.not(__.out());
let results = g.v().append(anon).to_list();
assert_eq!(results.len(), 1);
assert_eq!(results[0].as_vertex_id(), Some(tg.graphdb));
}
#[test]
fn anonymous_and_factory() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let anon = __.and_(vec![__.out(), __.in_()]);
let results = g.v().append(anon).to_list();
assert_eq!(results.len(), 3);
}
#[test]
fn anonymous_or_factory() {
let tg = create_small_graph();
let snapshot = tg.graph.snapshot();
let g = snapshot.gremlin();
let anon = __.or_(vec![__.has_label("person"), __.has_label("software")]);
let results = g.v().append(anon).to_list();
assert_eq!(results.len(), 4);
}