//! A view picker follows a view inspector without stealing semantic selection. use super::*; fn fixture() -> (App, Id, Id, Id) { let project = language::parse( r#"arcadia 6; project views "View switching" { oa_activity work "Inspect work" {} diagram first "Original concern" {} diagram second "Commands review" {} node original_work { diagram @first; element @work; } node copied_work { diagram @second; element @work; } }"#, ) .unwrap(); let id = |alias| { project .identities() .into_iter() .find(|(_, value)| *value == alias) .unwrap() .0 }; let (first, second, work) = (id("first"), id("second"), id("work")); let mut app = App::with_project(project); app.page = Page::Diagram; app.active_diagram = Some(second); app.selected = second; app.refresh_draft(); (app, first, second, work) } fn choose(app: &mut App, id: Id) { let _ = app.update(Message::Diagram(Choice { id, label: "Captured choice".into(), })); } fn field(app: &mut App, path: &str, value: &str) { let _ = app.update(Message::Field(path.into(), value.into())); } #[test] fn changing_visible_view_follows_its_clean_inspector_without_a_model_edit() { let (mut app, original, copy, _) = fixture(); let before = app.document.snapshot(); let revision = app.document.revision(); choose(&mut app, original); assert_eq!(app.active_diagram, Some(original)); assert_eq!(app.selected, original); assert_eq!(app.draft.as_ref().unwrap().original, original); assert_eq!( app.draft.as_ref().unwrap().inputs["/name"].raw, "Original concern" ); assert_eq!(app.project(), &before.decoded.project); assert_eq!(app.document.bundle(), &before.bundle); assert_eq!(app.document.revision(), revision); assert!(!app.document.can_undo()); field(&mut app, "/name", "Edited visible original"); assert!(app.apply()); assert_eq!( app.project().diagrams[&original].name, "Edited visible original" ); assert_eq!(app.project().diagrams[©].name, "Commands review"); } #[test] fn invalid_view_draft_blocks_the_switch_and_retains_raw_input() { let (mut app, original, copy, _) = fixture(); field(&mut app, "/id", "-"); let raw = serde_json::to_value(app.draft.as_ref().unwrap().recovery_snapshot()).unwrap(); let before = app.document.snapshot(); choose(&mut app, original); assert_eq!(app.active_diagram, Some(copy)); assert_eq!(app.selected, copy); assert_eq!( serde_json::to_value(app.draft.as_ref().unwrap().recovery_snapshot()).unwrap(), raw ); assert_eq!(app.project(), &before.decoded.project); assert_eq!(app.document.bundle(), &before.bundle); assert!(!app.document.can_undo()); } #[test] fn valid_pending_view_edit_applies_to_old_view_then_inspects_the_new_view() { let (mut app, original, copy, _) = fixture(); let before = app.document.snapshot(); field(&mut app, "/name", "Reviewed copy"); choose(&mut app, original); assert_eq!(app.project().diagrams[©].name, "Reviewed copy"); assert_eq!( app.project().diagrams[&original], before.decoded.project.diagrams[&original] ); assert_eq!(app.selected, original); assert_eq!(app.draft.as_ref().unwrap().original, original); let _ = app.update(Message::Undo); assert_eq!(app.project(), &before.decoded.project); assert_eq!(app.document.bundle(), &before.bundle); assert!(!app.document.can_undo()); } #[test] fn diagram_uuid_edit_follows_the_same_view_or_a_different_picker_target() { for same_view in [false, true] { let (mut app, original, copy, _) = fixture(); let changed = Id::from_u128(0xabcd123440008000000000000001); field(&mut app, "/id", &changed.to_string()); choose(&mut app, if same_view { copy } else { original }); let expected = if same_view { changed } else { original }; assert!(!app.project().diagrams.contains_key(©)); assert!(app.project().diagrams.contains_key(&changed)); assert_eq!(app.active_diagram, Some(expected)); assert_eq!(app.selected, expected); assert_eq!(app.draft.as_ref().unwrap().original, expected); assert!(!app.draft_dirty()); } } #[test] fn diagram_switch_preserves_an_independent_semantic_inspection() { let (mut app, original, _, work) = fixture(); let _ = app.update(Message::Select(work)); let before = app.document.snapshot(); choose(&mut app, original); assert_eq!(app.active_diagram, Some(original)); assert_eq!(app.selected, work); assert_eq!(app.draft.as_ref().unwrap().original, work); assert_eq!(app.project(), &before.decoded.project); assert_eq!(app.document.bundle(), &before.bundle); } #[test] fn stale_diagram_choice_never_applies_an_unrelated_valid_draft() { let (mut app, _, copy, _) = fixture(); field(&mut app, "/name", "Pending copy name"); let before = app.document.snapshot(); choose(&mut app, Id::new_v4()); assert_eq!(app.active_diagram, Some(copy)); assert_eq!(app.selected, copy); assert_eq!( app.draft.as_ref().unwrap().inputs["/name"].raw, "Pending copy name" ); assert_eq!(app.project(), &before.decoded.project); assert_eq!(app.document.bundle(), &before.bundle); assert!(!app.document.can_undo()); assert!(app.status.contains("no longer exists")); }