use crate::tools::canonical_tool_names;
use pretty_assertions::assert_eq;
use super::*;
fn matcher(patterns: &[&str]) -> ToolMatcher {
ToolMatcher::new(
patterns
.iter()
.map(|pattern| (*pattern).to_owned())
.collect(),
canonical_tool_names(),
)
.expect("pattern list is valid")
}
#[test]
fn patterns_match_exact_names_or_a_trailing_star_prefix() {
let any = ToolMatcher::any();
for (case, tools, tool, expected) in [
("omitted list", &any, "read_file", true),
(
"exact name",
&matcher(&["bash", "powershell"]),
"powershell",
true,
),
(
"exact name only",
&matcher(&["bash", "powershell"]),
"read_file",
false,
),
("trailing star", &matcher(&["web*"]), "web_search", true),
(
"trailing star prefix only",
&matcher(&["web*"]),
"bash",
false,
),
("bare star", &matcher(&["*"]), "anything", true),
] {
assert_eq!(tools.matches(tool), expected, "{case}");
}
}
#[test]
fn an_unsupported_glob_or_unknown_name_fails_at_load() {
let unsupported = |pattern: &str| ToolMatcherError::UnsupportedGlob {
pattern: pattern.into(),
};
let unknown = |pattern: &str| ToolMatcherError::UnknownTool {
pattern: pattern.into(),
};
for (case, patterns, expected) in [
(
"empty list is not all tools",
vec![],
ToolMatcherError::Empty,
),
(
"blank pattern",
vec![" ".into()],
ToolMatcherError::BlankPattern,
),
("leading star", vec!["*_file".into()], unsupported("*_file")),
("inner star", vec!["re*d*".into()], unsupported("re*d*")),
("wrong case", vec!["Bash".into()], unknown("Bash")),
("non-canonical name", vec!["shell".into()], unknown("shell")),
(
"prefix selecting nothing",
vec!["zzz*".into()],
unknown("zzz*"),
),
] {
assert_eq!(
ToolMatcher::new(patterns, canonical_tool_names()),
Err(expected),
"{case}"
);
}
}
#[test]
fn the_description_lists_patterns_as_written() {
for (tools, expected) in [
(ToolMatcher::any(), "*"),
(matcher(&["bash", "powershell"]), "bash, powershell"),
(matcher(&["web*"]), "web*"),
] {
assert_eq!(tools.describe(), expected);
}
}
#[test]
fn partial_edit_tool_lists_report_missing_edit_tools() {
let cases: [(&[&str], &[&str]); 5] = [
(&["edit", "write"], &["str_replace", "apply_patch"]),
(&["str_replace"], &["apply_patch", "edit"]),
(&["edit", "apply_patch", "str_replace"], &[]),
(&["bash", "write"], &[]),
(&["*"], &[]),
];
for (patterns, missing) in cases {
assert_eq!(
matcher(patterns).missing_edit_tools(),
missing.to_vec(),
"{patterns:?}"
);
}
assert_eq!(ToolMatcher::any().missing_edit_tools(), Vec::<&str>::new());
}