fix(graph): make turn-cap and template checks consistent across validation modes
This commit is contained in:
4 files changed
+98
-9
No files matched your search
+38
-6
@@ -320,14 +320,24 @@ pub(super) fn template_root_keys(template: &str) -> Vec<String> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
// Whether `s` is exactly one `{{key}}` reference and nothing else, after the
|
||||
// same trim `interpolate_raw` applies, so this accepts exactly the strings the
|
||||
// runtime resolves as a pure reference.
|
||||
// Whether `s` is exactly one `{{key}}` reference and nothing else (after the
|
||||
// same trim `interpolate_raw` applies) whose path parses with the grammar
|
||||
// `get_nested_value` uses, so this accepts exactly the strings the runtime
|
||||
// can resolve as a pure reference.
|
||||
pub(super) fn is_lone_template(s: &str) -> bool {
|
||||
let s = s.trim();
|
||||
TEMPLATE_VAR_RE
|
||||
.find(s)
|
||||
.is_ok_and(|m| m.is_some_and(|m| m.start() == 0 && m.end() == s.len()))
|
||||
let Ok(Some(m)) = TEMPLATE_VAR_RE.captures(s) else {
|
||||
return false;
|
||||
};
|
||||
let whole = m.get(0).expect("group 0 always present");
|
||||
if whole.start() != 0 || whole.end() != s.len() {
|
||||
return false;
|
||||
}
|
||||
let path = m.get(1).expect("template regex has one group").as_str();
|
||||
let mut parts = path.split('.');
|
||||
let first = parts.next().and_then(split_indices);
|
||||
first.is_some_and(|(name, _)| !name.is_empty())
|
||||
&& parts.all(|part| split_indices(part).is_some())
|
||||
}
|
||||
|
||||
fn value_to_string(value: &Value) -> String {
|
||||
@@ -973,6 +983,28 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_lone_template_matches_runtime_path_grammar() {
|
||||
for accepted in [
|
||||
"{{a.b[0][1].c}}",
|
||||
"{{a[0][1]}}",
|
||||
"{{a.}}",
|
||||
"{{a..b}}",
|
||||
"{{a.[0]}}",
|
||||
] {
|
||||
assert!(
|
||||
is_lone_template(accepted),
|
||||
"{accepted:?} resolves at run time and must be accepted"
|
||||
);
|
||||
}
|
||||
for rejected in ["{{limits[foo]}}", "{{a[]}}", "{{a[0}}", "{{.a}}"] {
|
||||
assert!(
|
||||
!is_lone_template(rejected),
|
||||
"{rejected:?} never resolves at run time and must be rejected"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interpolate_raw_inner_spaces_treated_as_mixed() {
|
||||
let manager = manager_with(&[("k", json!("v"))]);
|
||||
|
||||
Reference in new issue
Block a user