Implement and archive Phase 5 integration acceptance

This commit is contained in:
2026-09-07 10:38:58 +02:00
parent cc82830889
commit 86c3ebeb6d
18 changed files with 1224 additions and 39 deletions

View File

@@ -924,3 +924,63 @@ fn events_with_the_same_name_are_local_to_their_form() {
.code()
.contains("SUB Form_LOAD"));
}
#[test]
fn indexed_controls_merge_atomically_with_bindings_and_undo() {
let t = Temp::new();
let mut a = t.app();
let root = root(&mut a);
let first = a
.design_place(C::CommandButton, 0, root, Rect::new(1, 1, 8, 2))
.unwrap();
property(&mut a, "INDEX", "0");
let target = node(&mut a, first).name;
let second = a
.design_place(C::CommandButton, 0, root, Rect::new(1, 4, 8, 2))
.unwrap();
let old = node(&mut a, second).name;
// Scalar and duplicate-index merges must leave every document untouched.
let before = a.design_form().unwrap().clone();
assert!(a.design_rename(&target).is_err());
assert_eq!(*a.design_form().unwrap(), before);
property(&mut a, "INDEX", "0");
let before = a.design_form().unwrap().clone();
assert!(a.design_rename(&target).is_err());
assert_eq!(*a.design_form().unwrap(), before);
property(&mut a, "INDEX", "1");
let unrelated = a
.design_place(C::TextBox, 0, root, Rect::new(20, 1, 8, 2))
.unwrap();
let unrelated_name = node(&mut a, unrelated).name;
property(&mut a, "INDEX", "2");
let before = a.design_form().unwrap().clone();
assert!(a.design_rename(&target).is_err());
assert_eq!(*a.design_form().unwrap(), before);
a.design_select(second, false).unwrap();
let doc = a.design_document().unwrap();
let source = format!("SUB {old}_Click(Index AS INTEGER)\n{old}(1).Caption = {target}(0).Caption\n{unrelated_name}(2).Text = \"kept\"\nEND SUB\n");
a.project.replace_text(doc, 0..0, &source).unwrap();
let before = a.design_form().unwrap().clone();
a.design_rename(&target).unwrap();
assert_eq!(node(&mut a, second).name, target);
let code = &a.design_form().unwrap().code;
assert!(code
.to_uppercase()
.contains(&format!("SUB {}_CLICK", target.to_uppercase())));
assert!(code.contains(&format!("{target}(1).Caption")));
assert!(code.contains(&format!("{unrelated_name}(2).Text")));
a.execute(Command::Undo);
assert_eq!(*a.design_form().unwrap(), before);
// Two handlers for the merged event are ambiguous and cannot be committed.
a.project
.replace_text(
doc,
0..0,
&format!("SUB {target}_Click(Index AS INTEGER)\nEND SUB\n"),
)
.unwrap();
let before = a.design_form().unwrap().clone();
a.design_select(second, false).unwrap();
assert!(a.design_rename(&target).is_err());
assert_eq!(*a.design_form().unwrap(), before);
}