Integrate diagnostic decorations and current-source Text input boundaries
This commit is contained in:
@@ -670,3 +670,208 @@ fn queued_group_toggle_cannot_mutate_a_reopened_or_rotated_visit() {
|
||||
assert!(!app.document.can_undo() && !app.document.can_redo());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn annotation_snapshot_requires_exact_current_bytes_and_publication() {
|
||||
let mut app = fixture();
|
||||
let original_model = app.document.snapshot();
|
||||
let original_source = app.source_snapshot.clone();
|
||||
let publication = app.source_annotation_snapshot().unwrap().publication;
|
||||
let initial = app.source_annotation_snapshot().unwrap();
|
||||
assert!(Arc::ptr_eq(&initial.source, &original_source));
|
||||
assert_eq!(initial.path, app.source_workspace.active);
|
||||
assert!(std::ptr::eq(
|
||||
initial.diagnostics,
|
||||
app.source_diagnostics.as_slice()
|
||||
));
|
||||
|
||||
// Republish identical diagnostics: old cached geometry must get a new identity.
|
||||
app.publish_source_diagnostics(app.source_diagnostics.clone());
|
||||
assert_ne!(
|
||||
app.source_annotation_snapshot().unwrap().publication,
|
||||
publication
|
||||
);
|
||||
|
||||
app.source_workspace
|
||||
.edit("// newer draft\n".into(), app.source_editor.cursor());
|
||||
assert!(
|
||||
app.source_annotation_snapshot().is_none(),
|
||||
"old publication after a real draft edit"
|
||||
);
|
||||
// A current source key alone must not bind new ranges to the old displayed text.
|
||||
app.publish_source_diagnostics(Vec::new());
|
||||
assert!(
|
||||
app.source_annotation_snapshot().is_none(),
|
||||
"displayed snapshot still contains old bytes"
|
||||
);
|
||||
app.show_source_file(false);
|
||||
let current = app.source_annotation_snapshot().unwrap();
|
||||
assert_eq!(current.source.as_ref(), "// newer draft\n");
|
||||
assert!(current.diagnostics.is_empty());
|
||||
assert!(Arc::ptr_eq(&original_model, &app.document.snapshot()));
|
||||
app.text_workspace.reset();
|
||||
assert!(app.source_annotation_snapshot().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn annotation_snapshot_tracks_real_file_round_trips_without_changing_model() {
|
||||
let mut project = Project::empty();
|
||||
let element = project
|
||||
.add_element(
|
||||
oa_core::Kind::Activity,
|
||||
oa_core::Layer::Oa,
|
||||
"Assess incident",
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
let mut app = App::with_project(project);
|
||||
app.page = Page::Text;
|
||||
app.publish_source_diagnostics(app.source_diagnostics.clone());
|
||||
let model = app.document.snapshot();
|
||||
let entry = app.source_workspace.entry.clone();
|
||||
let fragment = app.document.compiled().index.declarations[&element]
|
||||
.path
|
||||
.clone();
|
||||
assert_ne!(entry, fragment);
|
||||
for path in [&entry, &fragment, &entry] {
|
||||
let _ = app.update(Message::SourceFile(path.clone()));
|
||||
let current = app.source_annotation_snapshot().unwrap();
|
||||
assert_eq!(current.path, path);
|
||||
assert_eq!(
|
||||
current.source.as_ref(),
|
||||
app.source_workspace.files[path].text
|
||||
);
|
||||
assert!(Arc::ptr_eq(¤t.source, &app.source_snapshot));
|
||||
assert!(Arc::ptr_eq(&model, &app.document.snapshot()));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drawer_document_session_and_visit_guards_are_independently_required() {
|
||||
for component in 0..3 {
|
||||
for action in 0..3 {
|
||||
let mut app = fixture();
|
||||
app.text_workspace.show_drawer(Some(DrawerTab::Status));
|
||||
let mut captured = app.text_drawer_context();
|
||||
match component {
|
||||
0 => captured.document = Id::new_v4(),
|
||||
1 => captured.session = Id::new_v4(),
|
||||
_ => captured.visit = Id::new_v4(),
|
||||
}
|
||||
app.queue_source_reveal(app.source_editor.cursor(), false);
|
||||
let reveal = app.source_reveal_ticket();
|
||||
assert!(reveal.is_some());
|
||||
let interaction = app.source_symbols.interaction;
|
||||
let cursor = app.source_editor.cursor();
|
||||
let accepted = app.document.snapshot();
|
||||
let raw = app.source_workspace.bundle();
|
||||
let current = app.text_drawer_context();
|
||||
let height = app.text_workspace.drawer_height();
|
||||
let event = match action {
|
||||
0 => Event::ShowDrawer(captured, DrawerTab::Problems),
|
||||
1 => Event::HideDrawer(captured),
|
||||
_ => Event::ResizeDrawer(captured, height + 60.),
|
||||
};
|
||||
send(&mut app, event);
|
||||
assert_eq!(app.text_drawer_context(), current);
|
||||
assert_eq!(app.text_workspace.drawer(), Some(DrawerTab::Status));
|
||||
assert_eq!(app.text_workspace.drawer_height(), height);
|
||||
assert_eq!(app.source_reveal_ticket(), reveal);
|
||||
assert_eq!(app.source_symbols.interaction, interaction);
|
||||
assert_eq!(app.source_editor.cursor(), cursor);
|
||||
assert_eq!(app.source_workspace.bundle(), raw);
|
||||
assert!(Arc::ptr_eq(&accepted, &app.document.snapshot()));
|
||||
assert!(!app.document.can_undo() && !app.document.can_redo());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
fn actual_chooser_blocks_diagnostic_actions_and_mounted_hover_until_closed() {
|
||||
use oa_core::{language::Diagnostic, source_project::SourceDiagnostic, validation::Severity};
|
||||
for republish in [false, true] {
|
||||
let mut app = fixture();
|
||||
assert!(app.source_workspace.text().starts_with("arcadia"));
|
||||
app.publish_source_diagnostics(vec![SourceDiagnostic {
|
||||
path: app.source_workspace.active.clone(),
|
||||
diagnostic: Diagnostic {
|
||||
severity: Severity::Warning,
|
||||
code: "union".into(),
|
||||
message: "Union diagnostic details".into(),
|
||||
object_id: None,
|
||||
field: None,
|
||||
line: 1,
|
||||
column: 1,
|
||||
span: Span { start: 0, end: 7 },
|
||||
},
|
||||
related: Vec::new(),
|
||||
}]);
|
||||
let show = Event::ShowDrawer(app.text_drawer_context(), DrawerTab::Problems);
|
||||
send(&mut app, show);
|
||||
let old_target = app.text_diagnostic_message(location(&app, 0, 7)).unwrap();
|
||||
let mut mounted = crate::source_annotations::AppMounted::new(
|
||||
app.source_annotation_snapshot().unwrap(),
|
||||
app.source_navigation_available(),
|
||||
app.source_symbols.raw_interaction.clone(),
|
||||
);
|
||||
mounted.assert_hover(true);
|
||||
let open = app.diagram_usage_message(app.project().id);
|
||||
let _ = app.update(open);
|
||||
let token = app
|
||||
.diagram_usages
|
||||
.as_ref()
|
||||
.expect("actual chooser opened")
|
||||
.token;
|
||||
assert!(!app.source_navigation_available());
|
||||
let accepted = app.document.snapshot();
|
||||
let raw = app.source_workspace.bundle();
|
||||
let cursor = app.source_editor.cursor();
|
||||
let interaction = app.source_symbols.interaction;
|
||||
let reveal = app.source_reveal_ticket();
|
||||
if republish {
|
||||
app.publish_source_diagnostics(app.source_diagnostics.clone());
|
||||
}
|
||||
mounted.refresh(
|
||||
app.source_annotation_snapshot().unwrap(),
|
||||
app.source_navigation_available(),
|
||||
);
|
||||
mounted.assert_hover(false);
|
||||
let _ = app.update(old_target.clone());
|
||||
assert_eq!(app.source_symbols.interaction, interaction);
|
||||
assert_eq!(app.source_reveal_ticket(), reveal);
|
||||
assert_eq!(app.diagram_usages.as_ref().unwrap().token, token);
|
||||
assert_eq!(app.diagram_lookup_in_flight, Some(token));
|
||||
assert_eq!(app.source_editor.cursor(), cursor);
|
||||
assert_eq!(app.source_workspace.bundle(), raw);
|
||||
assert!(Arc::ptr_eq(&accepted, &app.document.snapshot()));
|
||||
let _ = app.update(Message::DiagramUsage(crate::diagram_usage::Event::Close(
|
||||
token,
|
||||
)));
|
||||
assert!(app.source_navigation_available());
|
||||
mounted.refresh(
|
||||
app.source_annotation_snapshot().unwrap(),
|
||||
app.source_navigation_available(),
|
||||
);
|
||||
mounted.assert_hover(true);
|
||||
if republish {
|
||||
let interaction = app.source_symbols.interaction;
|
||||
let reveal = app.source_reveal_ticket();
|
||||
let _ = app.update(old_target);
|
||||
assert_eq!(
|
||||
app.source_symbols.interaction, interaction,
|
||||
"old publication stays stale after modal closes"
|
||||
);
|
||||
assert_eq!(app.source_reveal_ticket(), reveal);
|
||||
}
|
||||
let target = app.text_diagnostic_message(location(&app, 0, 7)).unwrap();
|
||||
let _ = app.update(target);
|
||||
assert!(
|
||||
app.source_reveal_ticket().is_some(),
|
||||
"fresh admitted location still navigates"
|
||||
);
|
||||
assert_eq!(app.source_workspace.bundle(), raw);
|
||||
assert!(Arc::ptr_eq(&accepted, &app.document.snapshot()));
|
||||
assert!(!app.document.can_undo() && !app.document.can_redo());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user