use super::*;
#[test]
fn test_mutable_never_reassigned() {
let diags = lint_source(
r"
pipeline default(task) {
let x = 1
log(x)
}
",
);
assert!(
has_rule(&diags, "mutable-never-reassigned"),
"expected mutable-never-reassigned warning, got: {diags:?}"
);
}
#[test]
fn test_mutable_reassigned_ok() {
let diags = lint_source(
r"
pipeline default(task) {
let x = 1
x = 2
log(x)
}
",
);
assert!(
!has_rule(&diags, "mutable-never-reassigned"),
"reassigned let should not trigger mutable-never-reassigned: {diags:?}"
);
}
#[test]
fn test_fix_mutable_never_reassigned() {
let source = "pipeline default(task) {\n let x = 10\n log(x)\n}";
let diags = lint_source(source);
let fix = get_fix(&diags, "mutable-never-reassigned");
assert!(fix.is_some(), "expected fix for mutable-never-reassigned");
let result = apply_fixes(source, &diags);
assert!(
result.contains("const x = 10"),
"expected let→const, got: {result}"
);
assert!(
!result.contains("let x"),
"let should be replaced, got: {result}"
);
}
#[test]
fn test_fix_shadowed_loop_local_preserves_execution() {
let source = r#"
pipeline default(task) {
let pins = []
for line in ["alpha", "beta"] {
let pin = {name: line}
pins = pins + [pin]
}
const labels = pins.map({ pin -> pin.name })
log(labels.join(","))
}
"#;
let diagnostics = lint_source(source);
let fixed = apply_fixes(source, &diagnostics);
assert!(
fixed.contains("const pin = {name: line}"),
"expected the loop-local `pin` fix, got: {fixed}"
);
assert_eq!(
execute_strict_source(source),
execute_strict_source(&fixed),
"let-to-const autofix must preserve runtime behavior under parameter shadowing"
);
}
#[test]
fn test_compound_assignment_counts_as_reassignment() {
let diags = lint_source(
r"
pipeline default(task) {
let x = 1
x += 1
log(x)
}
",
);
assert!(
!has_rule(&diags, "mutable-never-reassigned"),
"compound-assigned let must not be flagged: {diags:?}"
);
}
#[test]
fn test_index_and_member_reassignment_counts() {
let index = lint_source(
r"
pipeline default(task) {
let xs = [1]
xs[0] = 2
log(xs)
}
",
);
assert!(
!has_rule(&index, "mutable-never-reassigned"),
"index-reassigned let must not be flagged: {index:?}"
);
let member = lint_source(
r"
pipeline default(task) {
let o = {a: 1}
o.a = 2
log(o)
}
",
);
assert!(
!has_rule(&member, "mutable-never-reassigned"),
"member-reassigned let must not be flagged: {member:?}"
);
}
#[test]
fn test_destructuring_binding_not_tightened() {
let diags = lint_source(
r"
pipeline default(task) {
const src = {a: 1, b: 2}
let {a, b} = src
a = 9
log(a)
log(b)
}
",
);
assert!(
!has_rule(&diags, "mutable-never-reassigned"),
"destructuring binding must not be tightened: {diags:?}"
);
}
#[test]
fn test_const_binding_is_idempotent() {
let diags = lint_source(
r"
pipeline default(task) {
const x = 10
log(x)
}
",
);
assert!(
!has_rule(&diags, "mutable-never-reassigned"),
"const binding must not be flagged: {diags:?}"
);
}