Test multiline State label group commit and exact history

This commit is contained in:
2026-09-24 16:02:45 -07:00
parent a2b8204f8b
commit 66278ed33b
@@ -323,3 +323,141 @@ fn state_multiline_label_group_preview_replaces_old_hit_rectangle_and_cancel_res
);
assert_eq!(f.project, before);
}
#[test]
fn state_multiline_label_group_commit_matches_fixed_project_and_one_step_history() {
let (f, edge, _) = multiline_label_fixture();
let b = placement(&f, f.b);
let c = placement(&f, f.c);
let before = f.project.clone();
// Declare the complete expected model before driving input. No event, preview,
// movement planner or resulting document supplies the expected displacement.
let mut expected = before.clone();
for id in [b, c] {
let node = expected
.diagrams
.get_mut(&f.diagram)
.unwrap()
.nodes
.get_mut(&id)
.unwrap();
node.position.x += 40.;
node.position.y += 40.;
}
let original_route = before.diagrams[&f.diagram].routes[0].clone();
let mut document = Document::from_project(before.clone(), Default::default()).unwrap();
let original_source = document.bundle().clone();
let mut view_canvas = canvas(&f, Tool::Select, 0.75);
let selection = group_selection(&view_canvas, [Target::Placement(b), Target::Placement(c)]);
let snapshot = selection
.snapshot(selection_context(view_canvas.context))
.unwrap();
view_canvas.selection = Some(&selection);
view_canvas.selected = f.c;
let mut state = State::default();
let baseline = view_canvas.scene(&state).unwrap();
let baseline_label = &baseline.routed.edges[&edge].label;
assert_eq!(baseline_label.center, Position { x: 440., y: 260. });
// Explicit 0.75 scale: thirty screen pixels is the declared forty world
// units. The nonzero pan/origin and ordered pointer helpers stay in play.
let start = screen(&view_canvas, Point::new(780., 200.));
let end = start + Vector::new(30., 30.);
motion(&view_canvas, &mut state, start, end);
assert!(
input(
&view_canvas,
&mut state,
mouse::Event::ButtonPressed(mouse::Button::Left),
end
)
.is_none()
);
assert!(state.group.is_some());
motion(&view_canvas, &mut state, end, end);
let preview = view_canvas
.scene_with_bounds(&state, Some(bounds()))
.unwrap();
let preview_label = &preview.routed.edges[&edge].label;
assert_eq!(preview_label.center, Position { x: 480., y: 300. });
assert_eq!(
preview_label.bounds.position,
Position {
x: baseline_label.bounds.position.x + 40.,
y: baseline_label.bounds.position.y + 40.,
}
);
assert_eq!(preview_label.bounds.size, baseline_label.bounds.size);
assert_eq!(preview_label.state_layout, baseline_label.state_layout);
assert_eq!(
f.project, before,
"Preview must not author its derived label"
);
let event = input(
&view_canvas,
&mut state,
mouse::Event::ButtonReleased(mouse::Button::Left),
end,
)
.unwrap();
let Event::Selection(SelectionEvent::Move(actual_snapshot, delta)) = event else {
panic!("Expected a group movement event, got {event:?}");
};
assert_eq!(actual_snapshot, snapshot);
assert_eq!(delta, Position { x: 40., y: 40. });
assert!(state.group.is_none() && state.press.is_none());
assert!(
input(
&view_canvas,
&mut state,
mouse::Event::ButtonReleased(mouse::Button::Left),
end
)
.is_none()
);
// This is the same production snapshot-to-command boundary used by App's
// SelectionEvent::Move handler; App admission has its existing separate tests.
let ids = crate::app::multiselect::placements(&actual_snapshot).unwrap();
let command =
oa_core::diagram_edit::translate_placements(document.project(), f.diagram, &ids, delta)
.unwrap();
document.execute(command).unwrap();
assert_eq!(document.project(), &expected);
assert_eq!(
document.project().diagrams[&f.diagram].routes[0],
original_route,
"Authored fraction, offset, attachments and empty waypoints remain exact"
);
let committed = StateCanvas {
project: document.project(),
..canvas(&f, Tool::Select, 0.75)
}
.scene(&State::default())
.unwrap();
assert_eq!(
committed.routed.edges[&edge].label, *preview_label,
"Measured settled label, including raw text and every line cell, matches preview"
);
let edited_source = document.bundle().clone();
assert_ne!(
edited_source, original_source,
"The group move is a real source edit"
);
assert!(document.undo());
assert_eq!(document.project(), &before);
assert_eq!(document.bundle(), &original_source);
assert!(
!document.undo(),
"One group release produces exactly one history entry"
);
assert!(document.redo());
assert_eq!(document.project(), &expected);
assert_eq!(document.bundle(), &edited_source);
assert!(!document.redo());
assert_eq!(
selection
.snapshot(selection_context(view_canvas.context))
.unwrap(),
snapshot
);
assert_eq!(f.project, before);
}