Test multiline State label group commit and exact history
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user