Test exact and fractional scenario spacing input separately
This commit is contained in:
@@ -328,3 +328,71 @@ fn zoomed_out_message_tolerance_matches_actual_canvas_hit() {
|
||||
state.begin_spacing(doc.project(), event).unwrap();
|
||||
assert_eq!(state.spacing_token(), Some(token));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fractional_screen_packet_preserves_subpixel_motion_in_preview_and_finish() {
|
||||
let (doc, owner, diagram, _, message) = fixture();
|
||||
let original = doc.snapshot();
|
||||
assert!(doc.project().diagrams[&diagram].layout.is_none());
|
||||
let mut state = State::default();
|
||||
let document = Id::new_v4();
|
||||
state.enter_representation(document, owner, Representation::Saved { diagram });
|
||||
state.presentation.viewport = Some(Size::new(900., 600.));
|
||||
state.presentation.fit = false;
|
||||
state.presentation.zoom = Some(0.5);
|
||||
// 406 + 2^-15 puts the press just below the 512 screen-coordinate boundary.
|
||||
state.presentation.pan = Vector::new(0., f32::from_bits(0x43cb_0001));
|
||||
let camera = state.camera_boundary();
|
||||
let context = state.context(document, owner, doc.revision(), 4).unwrap();
|
||||
let baseline = resolve(doc.project(), context.representation, message).unwrap();
|
||||
let line = baseline.scene.lines.iter().find(|line| line.id == message).unwrap();
|
||||
assert_eq!(line.points[0].y, 148.);
|
||||
let begin = packet(doc.project(), &state, context, 9, Target::Message(message));
|
||||
let Event::Begin { press_screen, canvas_bounds, scale, pan, .. } = begin else {
|
||||
unreachable!()
|
||||
};
|
||||
assert_eq!(canvas_bounds.y, 23.);
|
||||
assert_eq!(scale, 0.5);
|
||||
assert_eq!(pan.y.to_bits(), 0x43cb_0001);
|
||||
assert_eq!(press_screen.y.to_bits(), 0x43fb_8001); // 503 + 2^-15.
|
||||
let end = press_screen + Vector::new(0., 10.);
|
||||
assert_eq!(end.y, 513.);
|
||||
assert!(canvas_bounds.contains(press_screen) && canvas_bounds.contains(end));
|
||||
// The submitted f32 displacement is 10 - 2^-15, not exactly 10.
|
||||
assert_eq!((end.y - press_screen.y).to_bits(), 0x411f_ffe0);
|
||||
assert_eq!(((end.y - press_screen.y) / scale).to_bits(), 0x419f_ffe0);
|
||||
// Independent oracle: 148 + (10 - 2^-15) / .5 = 168 - 2^-14.
|
||||
let expected_y = f32::from_bits(0x4327_fffc);
|
||||
let mut expected = original.decoded.project.clone();
|
||||
expected.diagrams.get_mut(&diagram).unwrap().layout = Some(
|
||||
oa_core::DiagramLayout::Scenario(oa_core::ScenarioLayout {
|
||||
lanes: vec![],
|
||||
messages: vec![oa_core::ScenarioMessagePosition {
|
||||
address: oa_core::OccurrenceEndpoint {
|
||||
references: vec![],
|
||||
occurrence: message,
|
||||
},
|
||||
send_y: expected_y,
|
||||
}],
|
||||
}),
|
||||
);
|
||||
state.begin_spacing(doc.project(), begin).unwrap();
|
||||
state.move_spacing(end);
|
||||
let preview = state.spacing.as_ref().unwrap().preview.as_ref().unwrap();
|
||||
assert_eq!(preview.project, expected);
|
||||
let line = preview.geometry.scene.lines.iter().find(|line| line.id == message).unwrap();
|
||||
assert_eq!(line.points[0].y.to_bits(), expected_y.to_bits());
|
||||
let Finish::Commit { command, selected, scale, pan } = state.finish_spacing(end).unwrap() else {
|
||||
panic!("fractional motion must remain a commit")
|
||||
};
|
||||
assert_eq!(selected, message);
|
||||
assert_eq!(scale, 0.5);
|
||||
assert_eq!(pan.y.to_bits(), 0x43cb_0001);
|
||||
let committed = oa_core::execute_batch(doc.project(), &[command]).unwrap();
|
||||
assert_eq!(committed, expected);
|
||||
assert!(state.spacing_token().is_none());
|
||||
assert_eq!(doc.project(), &original.decoded.project);
|
||||
assert_eq!(doc.compiled().bundle, original.bundle);
|
||||
assert!(!doc.dirty() && !doc.can_undo() && !doc.can_redo());
|
||||
assert!(camera == state.camera_boundary());
|
||||
}
|
||||
|
||||
@@ -156,8 +156,26 @@ async fn saved_message_same_batch_pointer_events_commit_once_and_one_undo_redo_r
|
||||
let target = id(&app, "updated_report");
|
||||
let before = app.document.snapshot();
|
||||
let revision = app.document.revision();
|
||||
let start = screen(&mut mounted, &app, Point::new(400., 252.));
|
||||
let projected = screen(&mut mounted, &app, Point::new(400., 252.));
|
||||
// This fixture asks for exactly +20 world units. A fractional start near a
|
||||
// screen-coordinate exponent boundary need not retain an exact +10 delta.
|
||||
let start = Point::new(projected.x.round(), projected.y.round());
|
||||
let mut geometry = resolved(&app);
|
||||
let camera = app.behavior.scenario.presentation.camera(geometry.bounds);
|
||||
assert_eq!(camera.scale, 0.5);
|
||||
let bounds = mounted.geometry(&app).bounds("scenario-viewport");
|
||||
let world = Point::new(
|
||||
(start.x - bounds.x - camera.pan.x) / camera.scale,
|
||||
(start.y - bounds.y - camera.pan.y) / camera.scale,
|
||||
);
|
||||
geometry.scene.scale = camera.scale;
|
||||
geometry.scene.camera_pan = camera.pan;
|
||||
let hit = geometry.scene.hit_item(world).unwrap();
|
||||
assert_eq!(hit.id, target);
|
||||
assert_eq!(hit.role, crate::behavior::SceneHitRole::MessageBody);
|
||||
let end = start + Vector::new(0., 10.); // .5 display scale: +20 authored y.
|
||||
assert_eq!(end.y - start.y, 10.);
|
||||
assert!(bounds.contains(start) && bounds.contains(end));
|
||||
let messages = mounted
|
||||
.batch(
|
||||
&mut app,
|
||||
|
||||
Reference in New Issue
Block a user