diff --git a/crates/oa-desktop/src/app/scenario_spacing/group_tests.rs b/crates/oa-desktop/src/app/scenario_spacing/group_tests.rs index 764c2d5b..0f3e6030 100644 --- a/crates/oa-desktop/src/app/scenario_spacing/group_tests.rs +++ b/crates/oa-desktop/src/app/scenario_spacing/group_tests.rs @@ -60,6 +60,38 @@ fn either_pressed_member_moves_complete_group_and_preserves_primary_source_and_o for messages in [false, true] { for pressed_index in 0..2 { let (mut app, ids) = group(messages, true); + // Automatic lane order depends on generated identities. Give this + // literal geometry oracle explicit authored starting coordinates. + let c = app.scenario_context().unwrap(); + let Representation::Saved { diagram } = c.representation else { + unreachable!() + }; + let mut initial = app.project().clone(); + let mut members = ids.to_vec(); + members.sort(); + let mut layout = ScenarioLayout::default(); + for member in members { + if messages { + layout.messages.push(ScenarioMessagePosition { + address: OccurrenceEndpoint { + references: vec![], + occurrence: member, + }, + send_y: if member == ids[0] { 148. } else { 240. }, + }); + } else { + layout.lanes.push(ScenarioLanePosition { + lifeline: member, + x: if member == ids[0] { 160. } else { 400. }, + }); + } + } + initial.diagrams.get_mut(&diagram).unwrap().layout = + Some(DiagramLayout::Scenario(layout)); + app.document = + Document::from_project(initial, oa_core::source_project::ProjectLimits::default()) + .unwrap(); + app.sync(); let original = app.document.snapshot(); let original_selection = app.multiselect_snapshot().unwrap(); let primary = app.selected; diff --git a/crates/oa-desktop/src/behavior/scenario/workspace/details_tests.rs b/crates/oa-desktop/src/behavior/scenario/workspace/details_tests.rs index 20b48445..5903cd29 100644 --- a/crates/oa-desktop/src/behavior/scenario/workspace/details_tests.rs +++ b/crates/oa-desktop/src/behavior/scenario/workspace/details_tests.rs @@ -388,13 +388,16 @@ fn opening_scenario_properties_cancels_held_spacing_and_rejects_its_late_finish( CanvasEvent::Viewport(c, Size::new(900., 600.)) }); open_details(&mut app); - let begin = packet( + let mut begin = packet( app.project(), &app.behavior.scenario, app.scenario_context().unwrap(), app.camera_epoch, Target::Message(message), ); + if let Spacing::Begin { stamp, .. } = &mut begin { + stamp.selection_generation = app.multiselect_snapshot().unwrap().generation(); + } let Spacing::Begin { press_screen, .. } = begin else { panic!() }; @@ -557,9 +560,14 @@ async fn saved_selection_shift_survives_properties_focus_busy_rebuild_and_clears mounted.settle(&mut app).await; let first_at = at(&mut mounted, &app, first); let messages = mounted.click(&mut app, first_at).await; - assert!(messages.iter().any(|message| matches!(message, - Message::ScenarioCanvas(CanvasEvent::Selection(event)) - if matches!(&event.intent, selection::Intent::Collapse(Target::ScenarioObject(id)) if *id == first)))); + // Saved group clicks now complete the captured spacing lifetime; its + // stationary outcome must retain the same selection-only collapse. + assert!(messages.iter().any(|message| matches!( + message, + Message::ScenarioCanvas(CanvasEvent::Spacing( + super::super::spacing::Event::Finish { .. } + )) + ))); assert_eq!( app.multiselect_snapshot().unwrap().targets(), &[Target::ScenarioObject(first)]