Correct mounted scenario camera and palette assertions

This commit is contained in:
2026-09-13 00:21:27 -07:00
parent 83e840e37f
commit cb5d50de03
2 changed files with 51 additions and 6 deletions
@@ -58,7 +58,7 @@ pub fn controls<'a>(
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Scope {
pub scenario_view: Option<(super::scenario_layout::Representation, Id)>,
pub(crate) scenario_view: Option<(super::scenario_layout::Representation, Id)>,
pub document: Id,
pub owner: Id,
pub revision: u64,
@@ -48,8 +48,28 @@ async fn production_scenario_canvas_keeps_bounds_draft_identity_and_camera_throu
mounted.pan(&mut app, start, start + delta).await;
let diff = app.behavior.scenario.presentation.pan - next_pan;
assert!(diff.x.hypot(diff.y) < 0.01);
let tool = mounted.geometry(&app).bounds("behavior-tool:A").center();
mounted.click(&mut app, tool).await;
// Iced operations report palette children in content coordinates.
// The preceding Action focus may have scrolled this retained palette.
let geometry = mounted.geometry(&app);
let scope = canvas_workspace::Scope::current(&app).unwrap();
let (palette, offset) = geometry.scrolls[&scope.control_id("palette-scroll")];
let tool = geometry.bounds("behavior-tool:A").center() - offset;
assert!(
palette.contains(tool),
"visible Action at {tool:?}: {palette:?}"
);
let chosen = mounted.click(&mut app, tool).await;
assert!(
chosen.iter().any(|message| matches!(
canvas_workspace::tests::intent_action(message),
Message::ScenarioCanvas(CanvasEvent::Choose(_, CanvasTool::Add(Tool::Action)))
)),
"Action palette click at scale {scale}, offset {offset:?}: {chosen:?}"
);
assert_eq!(
app.behavior.scenario.canvas_tool(f.owner),
CanvasTool::Add(Tool::Action)
);
let messages = mounted.click(&mut app, bounds.position() + desired).await;
assert!(
messages.iter().any(
@@ -57,7 +77,7 @@ async fn production_scenario_canvas_keeps_bounds_draft_identity_and_camera_throu
tool: Tool::Action, slot, lifeline: Some(line), ..
}) if *slot == expected && *line == f.sender)
),
"scale {scale}: {messages:?}"
"scale {scale}, expected slot {expected:?}: {messages:?}"
);
let session = app.behavior.scenario.form_session().unwrap();
let invocation = app.behavior.scenario.draft.as_ref().unwrap().invocation;
@@ -1337,7 +1357,18 @@ async fn production_scenario_camera_external_controls_bounds_and_retained_deltas
let bounds = mounted.geometry(&app).bounds("scenario-viewport");
let point = bounds.position() + iced::Vector::new(95., 90.);
let lifetime = app.camera_epoch;
let pan = app.behavior.scenario.presentation.pan;
// Fit stores no pan offset. A real drag starts from the displayed fitted
// camera, then materializes it before applying its ordered screen deltas.
let shown = app
.behavior
.scenario
.display(app.project(), f.owner, app.selected)
.unwrap();
let before_camera = app
.behavior
.scenario
.presentation
.camera(shown.bounds().unwrap());
let first = point + iced::Vector::new(13., 9.);
let last = first + iced::Vector::new(17., -3.);
let emitted = mounted
@@ -1352,7 +1383,21 @@ async fn production_scenario_camera_external_controls_bounds_and_retained_deltas
mouse::Cursor::Available(last),
)
.await;
assert_eq!(app.behavior.scenario.presentation.pan, pan + (last - point));
let expected_pan = before_camera.pan + (last - point);
let actual_pan = app.behavior.scenario.presentation.pan;
let difference = actual_pan - expected_pan;
assert!(
difference.x.hypot(difference.y) < 0.001,
"{boundary}: displayed pan {actual_pan:?} must follow {expected_pan:?}"
);
assert_eq!(
app.behavior.scenario.presentation.zoom,
Some(before_camera.scale)
);
assert!(
!app.behavior.scenario.presentation.fit,
"drag materializes the visible Fit camera"
);
assert_eq!(
app.camera_epoch, lifetime,
"own ordered deltas retain their lifetime"