use super::{Question, Stage, pipeline};
use crate::serve::protocol::Metric;
type TestResult = Result<(), Box<dyn std::error::Error>>;
#[test]
fn rerank_parses_words_and_keeps_the_stage_byte_span() -> TestResult {
let text = "patients | rerank(.body_vec; \"chest pain\"; cosine) | '$score'";
let plan = pipeline(text).map_err(|error| error.to_string())?;
let stage = plan.stages.first().ok_or("missing rerank stage")?;
assert_eq!(
stage.value,
Stage::Rerank {
field: "body_vec".to_owned(),
question: Question::Text("chest pain".to_owned()),
measure: Metric::Cosine,
}
);
assert_eq!(
text.get(stage.span.start..stage.span.end),
Some("rerank(.body_vec; \"chest pain\"; cosine)")
);
Ok(())
}
#[test]
fn rerank_parses_a_record_question_after_an_upstream_limit() -> TestResult {
let plan = pipeline(concat!(
"patients | similar(.a; record(\"p0\"); dot) | limit(20)",
" | rerank(.b; record(\"p1\"); l2)",
))
.map_err(|error| error.to_string())?;
let stage = plan.stages.last().ok_or("missing rerank stage")?;
assert_eq!(
stage.value,
Stage::Rerank {
field: "b".to_owned(),
question: Question::Record("p1".to_owned()),
measure: Metric::L2,
}
);
Ok(())
}
#[test]
fn rerank_refuses_missing_or_unknown_measures_and_empty_record_ids() -> TestResult {
for text in [
"patients | rerank(.b; \"words\")",
"patients | rerank(.b; \"words\"; pearson)",
"patients | rerank(.b; record(\"\"); dot)",
"patients | rerank(.b, .c; \"words\"; dot)",
] {
let error = pipeline(text).err().ok_or("invalid rerank was accepted")?;
assert!(error.to_string().contains("rerank") || error.to_string().contains("record"));
}
Ok(())
}
#[test]
fn rerank_after_jq_is_refused_at_its_word() -> TestResult {
let text = "patients | '.name' | rerank(.b; record(\"p0\"); dot)";
let error = pipeline(text).err().ok_or("rerank after jq was accepted")?;
assert_eq!(error.code(), "query_parse");
assert_eq!(
text.get(error.span().start..error.span().end),
Some("rerank")
);
Ok(())
}