use runlet::{CanonicalValue, Runtime, heal};
#[test]
fn statement_form_if_with_returnless_branches_heals_and_runs() {
let source = "
flag = 2 > 1
if flag {
a = 1
} else {
b = 2
}
return flag
";
let healed = heal(source).expect("statement-form if is healable");
assert!(
healed
.notes
.iter()
.any(|n| n.contains("control structures")),
"{:?}",
healed.notes
);
let runtime = Runtime::builder().build().unwrap();
let program = runtime
.compile(&healed.source)
.unwrap_or_else(|d| panic!("healed source must compile: {d:#?}\n{}", healed.source));
let execution = runtime.run(&program).unwrap();
assert_eq!(execution.value, CanonicalValue::Boolean(true));
}
#[test]
fn bare_final_expression_and_bare_statement_heal() {
let source = "
doubled = for x in [1, 2] limit 2 {
y = x * 2
y
}
return doubled
";
let healed = heal(source).expect("missing return is healable");
assert!(
healed.notes.iter().any(|n| n.contains("return")),
"{:?}",
healed.notes
);
let runtime = Runtime::builder().build().unwrap();
let execution = runtime
.run(&runtime.compile(&healed.source).unwrap())
.unwrap();
assert_eq!(
execution.value,
CanonicalValue::List(vec![CanonicalValue::Integer(2), CanonicalValue::Integer(4)])
);
}
#[test]
fn valid_and_unhealable_sources_return_none() {
assert!(
heal("x = 1\nreturn x").is_none(),
"valid source: no healing"
);
assert!(
heal("x = ((((\nreturn x").is_none(),
"garbage stays unhealable"
);
}
#[test]
fn v14_crm_transcript_shape_heals_to_the_semantic_errors() {
let source = r#"
digits = "4155550100"
final_digits = if text.length(digits) == 11 and text.starts_with(digits, "1") {
text.slice(digits, 1)
} else if text.length(digits) == 10 {
digits
} else {
fail("INVALID", "cannot parse")
}
final_digits = "+1" + final_digits
return final_digits
"#;
let healed = heal(source).expect("missing returns must heal");
let runtime = Runtime::builder().with_prelude().build().unwrap();
let diagnostics = runtime
.compile(&healed.source)
.expect_err("the rebinding is a real error that must survive healing");
assert!(
diagnostics.iter().all(|d| d.code != "RL1017"),
"syntax errors must be gone: {diagnostics:#?}"
);
assert!(
diagnostics
.iter()
.any(|d| d.code == "RL2106" && d.message.contains("immutable")),
"the rebinding surfaces with the immutability hint: {diagnostics:#?}"
);
}