use super::detect_hints;
use crate::wasm::diagnostics::Severity;
#[test]
fn filter_hint() {
let query = "ds:metric | filter tag == \"x\"";
let items = detect_hints(query);
assert_eq!(items.len(), 1);
assert!(matches!(items[0].severity, Severity::Hint));
assert_eq!(items[0].actions.len(), 1);
assert_eq!(items[0].actions[0].insert, "where");
assert_eq!(&query[items[0].span.from..items[0].span.to], "filter");
}
#[test]
fn where_no_hint() {
let query = "ds:metric | where tag == \"x\"";
let items = detect_hints(query);
assert!(items.is_empty(), "should not suggest for `where`");
}
#[test]
fn filter_hint_multiple() {
let query = "ds:metric | filter a == \"1\" | filter b == \"2\"";
let items = detect_hints(query);
assert_eq!(items.len(), 2, "should detect both `filter` keywords");
}
#[test]
fn filter_hint_mixed_where_and_filter() {
let query = "ds:metric | where a == \"1\" | filter b == \"2\"";
let items = detect_hints(query);
assert_eq!(items.len(), 1, "should only flag the `filter` keyword");
assert_eq!(&query[items[0].span.from..items[0].span.to], "filter");
}
#[test]
fn filter_hint_inside_ifdef_body() {
let query = "param $f: Option<string>;\nds:metric | ifdef($f) { filter tag == $f }";
let items = detect_hints(query);
let filter_hints: Vec<_> = items
.iter()
.filter(|i| i.message.contains("filter"))
.collect();
assert_eq!(filter_hints.len(), 1, "filter inside ifdef should hint");
assert_eq!(filter_hints[0].actions[0].insert, "where");
assert_eq!(
&query[filter_hints[0].span.from..filter_hints[0].span.to],
"filter"
);
}
#[test]
fn unnecessary_escape_plain_tag() {
let query = "ds:metric | filter `tag` == \"x\"";
let items = detect_hints(query);
let escape_hints: Vec<_> = items
.iter()
.filter(|i| i.message.contains("backtick"))
.collect();
assert_eq!(escape_hints.len(), 1);
assert!(matches!(escape_hints[0].severity, Severity::Hint));
assert_eq!(escape_hints[0].actions.len(), 1);
assert_eq!(escape_hints[0].actions[0].insert, "tag");
assert_eq!(
&query[escape_hints[0].span.from..escape_hints[0].span.to],
"`tag`"
);
}
#[test]
fn no_unnecessary_escape_for_hyphenated() {
let query = "ds:metric | filter `my-tag` == \"x\"";
let items = detect_hints(query);
assert!(
!items.iter().any(|i| i.message.contains("backtick")),
"hyphenated ident needs escaping"
);
}
#[test]
fn no_unnecessary_escape_for_leading_digit() {
let query = "ds:metric | filter `0abc` == \"x\"";
let items = detect_hints(query);
assert!(
!items.iter().any(|i| i.message.contains("backtick")),
"leading-digit ident needs escaping"
);
}
#[test]
fn no_unnecessary_escape_for_dotted() {
let query = "ds:metric | filter `my_tag.name` == \"x\"";
let items = detect_hints(query);
assert!(
!items.iter().any(|i| i.message.contains("backtick")),
"dotted ident needs escaping"
);
}
#[test]
fn unnecessary_escape_multiple() {
let query = "ds:metric | filter `a` == \"1\" and `b` == \"2\"";
let items = detect_hints(query);
let escape_hints: Vec<_> = items
.iter()
.filter(|i| i.message.contains("backtick"))
.collect();
assert_eq!(escape_hints.len(), 2, "should flag both escaped idents");
}
#[test]
fn no_hints_dataset_colon_no_metric() {
assert!(detect_hints("ds:").is_empty());
}
#[test]
fn no_hints_dataset_no_colon() {
assert!(detect_hints("ds").is_empty());
}
#[test]
fn no_hints_dataset_no_metric_with_filter() {
assert!(detect_hints("ds: | filter tag == \"x\"").is_empty());
}
#[test]
fn no_hints_dataset_no_colon_with_filter() {
assert!(detect_hints("ds | filter tag == \"x\"").is_empty());
}
#[test]
fn no_hints_backtick_dataset_no_metric_with_where() {
assert!(detect_hints("`my-dataset`: | where tag == \"x\"").is_empty());
}