use proptest::prelude::*;
use sdivi_patterns::queries::{category_for_node_kind, classify_hint};
use sdivi_patterns::PatternHintInput;
const NON_SPECIAL_NODE_KINDS: &[&str] = &[
"await_expression",
"class_declaration",
"class_definition",
"abstract_class_declaration",
"interface_declaration",
"impl_item",
"try_expression",
"match_expression",
"closure_expression",
"as_expression",
"type_cast_expression",
];
const TEST_LANGUAGES: &[&str] = &["rust", "python", "typescript", "javascript", "go", "java"];
proptest! {
#![proptest_config(ProptestConfig::with_cases(500))]
#[test]
fn prop_fall_through_matches_category_for_node_kind(
kind_idx in 0usize..NON_SPECIAL_NODE_KINDS.len(),
lang_idx in 0usize..TEST_LANGUAGES.len(),
text in "[a-zA-Z0-9._:! ]{0,40}",
) {
let node_kind = NON_SPECIAL_NODE_KINDS[kind_idx];
let language = TEST_LANGUAGES[lang_idx];
let hint = PatternHintInput {
node_kind: node_kind.to_string(),
text,
};
let got = classify_hint(&hint, language);
let expected: Vec<&'static str> = category_for_node_kind(node_kind, language)
.map(|c| vec![c])
.unwrap_or_default();
prop_assert_eq!(
got,
expected,
"classify_hint must fall through for node_kind={:?}, language={:?}",
node_kind,
language
);
}
#[test]
fn prop_unknown_kind_falls_through_to_empty(
suffix in "[a-z]{5,15}",
lang_idx in 0usize..TEST_LANGUAGES.len(),
text in "[a-zA-Z0-9._:! ]{0,30}",
) {
let node_kind = format!("unknown_test_{suffix}");
let language = TEST_LANGUAGES[lang_idx];
let hint = PatternHintInput {
node_kind: node_kind.clone(),
text,
};
let got = classify_hint(&hint, language);
let expected: Vec<&'static str> = category_for_node_kind(&node_kind, language)
.map(|c| vec![c])
.unwrap_or_default();
prop_assert_eq!(
got,
expected,
"classify_hint for unknown kind {:?} (language={:?}) must match \
category_for_node_kind — both must be empty for unrecognised node kinds",
node_kind,
language
);
}
#[test]
fn prop_text_does_not_affect_fall_through(
kind_idx in 0usize..NON_SPECIAL_NODE_KINDS.len(),
lang_idx in 0usize..TEST_LANGUAGES.len(),
text_a in "[a-zA-Z0-9._:! ]{0,30}",
text_b in "[a-zA-Z0-9._:! ]{0,30}",
) {
let node_kind = NON_SPECIAL_NODE_KINDS[kind_idx];
let language = TEST_LANGUAGES[lang_idx];
let hint_a = PatternHintInput { node_kind: node_kind.to_string(), text: text_a };
let hint_b = PatternHintInput { node_kind: node_kind.to_string(), text: text_b };
let result_a = classify_hint(&hint_a, language);
let result_b = classify_hint(&hint_b, language);
prop_assert_eq!(
result_a,
result_b,
"classify_hint for non-special node_kind={:?} must be text-agnostic",
node_kind
);
}
}