mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
Add symmetric assertion for inlay-hint hover disambiguation
This commit is contained in:
parent
b4f3ea7871
commit
5f371d806d
1 changed files with 90 additions and 63 deletions
|
|
@ -2266,71 +2266,98 @@ mod tests {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Hover in the middle of the first inlay's rendered text.
|
async fn assert_hovered_inlay(
|
||||||
let hover_position = cx.update_editor(|editor, window, cx| {
|
cx: &mut EditorLspTestContext,
|
||||||
let snapshot = editor.snapshot(window, cx);
|
hint_offset: usize,
|
||||||
let inlay_start = MultiBufferOffset(first_hint_offset).to_display_point(&snapshot);
|
label_len: u32,
|
||||||
let exact_unclipped = DisplayPoint::new(
|
expected_tooltip: &str,
|
||||||
inlay_start.row(),
|
expected_inlay_id: InlayId,
|
||||||
inlay_start.column() + (first_label.len() as u32 / 2),
|
) {
|
||||||
);
|
let hover_position = cx.update_editor(|editor, window, cx| {
|
||||||
let previous_valid = snapshot.clip_point(exact_unclipped, Bias::Left);
|
let snapshot = editor.snapshot(window, cx);
|
||||||
let next_valid = snapshot.clip_point(exact_unclipped, Bias::Right);
|
let inlay_start = MultiBufferOffset(hint_offset).to_display_point(&snapshot);
|
||||||
let nearest_valid = if previous_valid == next_valid {
|
let exact_unclipped =
|
||||||
previous_valid
|
DisplayPoint::new(inlay_start.row(), inlay_start.column() + label_len / 2);
|
||||||
} else {
|
let previous_valid = snapshot.clip_point(exact_unclipped, Bias::Left);
|
||||||
match snapshot.inlay_bias_at(exact_unclipped) {
|
let next_valid = snapshot.clip_point(exact_unclipped, Bias::Right);
|
||||||
Some(Bias::Left) => next_valid,
|
let nearest_valid = if previous_valid == next_valid {
|
||||||
Some(Bias::Right) => previous_valid,
|
previous_valid
|
||||||
None => previous_valid,
|
} else {
|
||||||
|
match snapshot.inlay_bias_at(exact_unclipped) {
|
||||||
|
Some(Bias::Left) => next_valid,
|
||||||
|
Some(Bias::Right) => previous_valid,
|
||||||
|
None => previous_valid,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
PointForPosition {
|
||||||
|
previous_valid,
|
||||||
|
next_valid,
|
||||||
|
nearest_valid,
|
||||||
|
exact_unclipped,
|
||||||
|
column_overshoot_after_line_end: 0,
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
PointForPosition {
|
cx.update_editor(|editor, window, cx| {
|
||||||
previous_valid,
|
editor.hover_state = HoverState::default();
|
||||||
next_valid,
|
editor.update_inlay_link_and_hover_points(
|
||||||
nearest_valid,
|
&editor.snapshot(window, cx),
|
||||||
exact_unclipped,
|
hover_position,
|
||||||
column_overshoot_after_line_end: 0,
|
None,
|
||||||
}
|
true,
|
||||||
});
|
false,
|
||||||
cx.update_editor(|editor, window, cx| {
|
window,
|
||||||
editor.update_inlay_link_and_hover_points(
|
cx,
|
||||||
&editor.snapshot(window, cx),
|
);
|
||||||
hover_position,
|
});
|
||||||
None,
|
cx.background_executor
|
||||||
true,
|
.advance_clock(Duration::from_millis(get_hover_popover_delay(cx) + 100));
|
||||||
false,
|
cx.background_executor.run_until_parked();
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
cx.background_executor
|
|
||||||
.advance_clock(Duration::from_millis(get_hover_popover_delay(&cx) + 100));
|
|
||||||
cx.background_executor.run_until_parked();
|
|
||||||
|
|
||||||
cx.update_editor(|editor, _, cx| {
|
cx.update_editor(|editor, _, cx| {
|
||||||
let hover_state = &editor.hover_state;
|
let hover_state = &editor.hover_state;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
hover_state.info_popovers.len(),
|
hover_state.info_popovers.len(),
|
||||||
1,
|
1,
|
||||||
"expected exactly one popover",
|
"expected exactly one popover for inlay {expected_inlay_id:?}",
|
||||||
);
|
);
|
||||||
let popover = hover_state.info_popovers.first().unwrap();
|
let popover = hover_state.info_popovers.first().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
popover.get_rendered_text(cx),
|
popover.get_rendered_text(cx),
|
||||||
"Foo",
|
expected_tooltip,
|
||||||
"popover content should match the first inlay (the one under the cursor), \
|
"popover content should match the inlay under the cursor, \
|
||||||
not the adjacent inlay one source character past it",
|
not the adjacent inlay one source character away",
|
||||||
);
|
);
|
||||||
let RangeInEditor::Inlay(highlight) = &popover.symbol_range else {
|
let RangeInEditor::Inlay(highlight) = &popover.symbol_range else {
|
||||||
panic!("expected an inlay popover, got {:?}", popover.symbol_range);
|
panic!("expected an inlay popover, got {:?}", popover.symbol_range);
|
||||||
};
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
highlight.inlay,
|
highlight.inlay, expected_inlay_id,
|
||||||
InlayId::Hint(0),
|
"popover should reference the hovered inlay",
|
||||||
"popover should reference the first inlay",
|
);
|
||||||
);
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
// Hover the first inlay (`::Foo`): the buffer-position window also covers
|
||||||
|
// the second hint past `;`, so the hovered-offset filter must pick the first.
|
||||||
|
assert_hovered_inlay(
|
||||||
|
&mut cx,
|
||||||
|
first_hint_offset,
|
||||||
|
first_label.len() as u32,
|
||||||
|
"Foo",
|
||||||
|
InlayId::Hint(0),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// Symmetric check: hover the second inlay (`::Bar`) and verify the filter
|
||||||
|
// picks the second hint despite the first hint also being in range.
|
||||||
|
assert_hovered_inlay(
|
||||||
|
&mut cx,
|
||||||
|
second_hint_offset,
|
||||||
|
second_label.len() as u32,
|
||||||
|
"Bar",
|
||||||
|
InlayId::Hint(1),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue