use super::*;
use plexus_conformance::load_cases_from_path;
use plexus_ir::mlir_text_to_plan;
use plexus_serde::{Expr, Op, VectorMetric};
use std::path::Path;
fn embedded_profile_plan() -> plexus_serde::Plan {
plexus_serde::Plan {
version: version(),
ops: vec![
Op::ConstRow,
Op::VectorScan {
input: 0,
collection: "docs".to_string(),
query_vector: Expr::ListLiteral {
items: vec![Expr::FloatLiteral(1.0), Expr::FloatLiteral(0.0)],
},
metric: VectorMetric::DotProduct,
top_k: 8,
approx_hint: false,
schema: vec![
ColDef {
name: "doc".to_string(),
kind: ColKind::Node,
logical_type: LogicalType::Unknown,
},
ColDef {
name: "score".to_string(),
kind: ColKind::Float64,
logical_type: LogicalType::Float64,
},
],
},
Op::Rerank {
input: 1,
score_expr: Expr::VectorSimilarity {
metric: VectorMetric::DotProduct,
lhs: Box::new(Expr::PropAccess {
col: 0,
prop: "embedding".to_string(),
}),
rhs: Box::new(Expr::ListLiteral {
items: vec![Expr::FloatLiteral(1.0), Expr::FloatLiteral(0.0)],
}),
},
top_k: 4,
schema: vec![
ColDef {
name: "doc".to_string(),
kind: ColKind::Node,
logical_type: LogicalType::Unknown,
},
ColDef {
name: "score".to_string(),
kind: ColKind::Float64,
logical_type: LogicalType::Float64,
},
],
},
Op::Return { input: 2 },
],
root_op: 3,
}
}
#[test]
fn embedded_graph_rag_profile_accepts_canonical_vector_plan() {
let plan = embedded_profile_plan();
let assessment = assess_embedded_graph_rag_plan(&plan);
assert!(assessment.supported, "{assessment:?}");
assert!(assessment.missing_required_ops.is_empty());
assert!(assessment.unsupported_ops.is_empty());
assert!(assessment.unsupported_exprs.is_empty());
validate_embedded_graph_rag_plan(&plan).expect("embedded profile validation should pass");
}
#[test]
fn embedded_graph_rag_profile_rejects_non_profile_plan_deterministically() {
let plan = plexus_serde::Plan {
version: version(),
ops: vec![
Op::ScanNodes {
labels: vec!["Doc".to_string()],
schema: vec![ColDef {
name: "doc".to_string(),
kind: ColKind::Node,
logical_type: LogicalType::Unknown,
}],
must_labels: Vec::new(),
forbidden_labels: Vec::new(),
est_rows: 10,
selectivity: 1.0,
graph_ref: None,
},
Op::Return { input: 0 },
],
root_op: 1,
};
let err = validate_embedded_graph_rag_plan(&plan).expect_err("plan should be rejected");
assert_eq!(err.assessment.profile, EMBEDDED_GRAPH_RAG_PROFILE);
assert_eq!(
err.assessment.missing_required_ops,
vec!["VectorScan", "Rerank"]
);
assert_eq!(err.assessment.unsupported_ops, vec!["ScanNodes"]);
assert!(err.assessment.unsupported_exprs.is_empty());
assert_eq!(
err.to_string(),
"plan is outside embedded-graph-rag-v0: missing required ops [VectorScan, Rerank]; unsupported ops [ScanNodes]"
);
}
#[test]
fn embedded_graph_rag_capability_gap_reports_missing_vector_surface() {
let mut caps = EngineCapabilities::full(VersionRange::new(
PlanSemver::new(0, 3, 0),
PlanSemver::new(0, 3, 0),
));
caps.supported_ops.remove(&OpKind::Rerank);
caps.supported_exprs.remove(&ExprKind::VectorSimilarity);
let gap = assess_embedded_graph_rag_capabilities(&caps);
assert!(!gap.supported);
assert_eq!(gap.missing_ops, vec!["Rerank"]);
assert_eq!(gap.missing_exprs, vec!["VectorSimilarity"]);
}
#[test]
fn embedded_graph_rag_fixture_matches_iridium_consumer_path() {
let fixture = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("src")
.join("tests")
.join("fixtures")
.join("vector")
.join("003_embedded_graphrag.feature");
let cases = load_cases_from_path(&fixture).expect("load embedded GraphRAG fixture");
let case = cases
.iter()
.find(|case| case.tags.iter().any(|tag| tag == "iridium-consumer"))
.expect("iridium-consumer fixture");
let plan = mlir_text_to_plan(
case.plan_mlir
.as_deref()
.expect("embedded GraphRAG fixture plan_mlir"),
)
.expect("parse embedded GraphRAG fixture");
let assessment = assess_embedded_graph_rag_plan(&plan);
assert!(assessment.supported, "{assessment:?}");
assert_eq!(plan.ops.len(), 5);
}