Finish writing test for the new autocompletion behavior
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
0f266cff54
commit
625beaaa9b
2 changed files with 97 additions and 20 deletions
|
@ -4000,7 +4000,8 @@ impl Editor {
|
||||||
if kind == Some(CharKind::Word) && word_range.to_inclusive().contains(&cursor_position)
|
if kind == Some(CharKind::Word) && word_range.to_inclusive().contains(&cursor_position)
|
||||||
{
|
{
|
||||||
let query = Self::completion_query(&buffer, cursor_position);
|
let query = Self::completion_query(&buffer, cursor_position);
|
||||||
smol::block_on(completion_state.filter(query.as_deref(), cx.background().clone()));
|
cx.background()
|
||||||
|
.block(completion_state.filter(query.as_deref(), cx.background().clone()));
|
||||||
self.show_completions(&ShowCompletions, cx);
|
self.show_completions(&ShowCompletions, cx);
|
||||||
} else {
|
} else {
|
||||||
self.hide_completions(cx);
|
self.hide_completions(cx);
|
||||||
|
@ -7133,15 +7134,7 @@ mod tests {
|
||||||
let (_, editor) = cx.add_window(|cx| build_editor(buffer, settings, cx));
|
let (_, editor) = cx.add_window(|cx| build_editor(buffer, settings, cx));
|
||||||
|
|
||||||
editor.update(&mut cx, |editor, cx| {
|
editor.update(&mut cx, |editor, cx| {
|
||||||
editor.select_ranges(
|
editor.select_ranges([Point::new(0, 3)..Point::new(0, 3)], None, cx);
|
||||||
[
|
|
||||||
Point::new(0, 3)..Point::new(0, 3),
|
|
||||||
Point::new(1, 3)..Point::new(1, 3),
|
|
||||||
Point::new(2, 3)..Point::new(2, 3),
|
|
||||||
],
|
|
||||||
None,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
editor.handle_input(&Input(".".to_string()), cx);
|
editor.handle_input(&Input(".".to_string()), cx);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -7150,8 +7143,8 @@ mod tests {
|
||||||
"/the/file",
|
"/the/file",
|
||||||
Point::new(0, 4),
|
Point::new(0, 4),
|
||||||
&[
|
&[
|
||||||
(Point::new(0, 4)..Point::new(0, 4), "first completion"),
|
(Point::new(0, 4)..Point::new(0, 4), "first_completion"),
|
||||||
(Point::new(0, 4)..Point::new(0, 4), "second completion"),
|
(Point::new(0, 4)..Point::new(0, 4), "second_completion"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
@ -7189,6 +7182,71 @@ mod tests {
|
||||||
.unindent()
|
.unindent()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
editor.update(&mut cx, |editor, cx| {
|
||||||
|
editor.select_ranges(
|
||||||
|
[
|
||||||
|
Point::new(1, 3)..Point::new(1, 3),
|
||||||
|
Point::new(2, 5)..Point::new(2, 5),
|
||||||
|
],
|
||||||
|
None,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
|
||||||
|
editor.handle_input(&Input(" ".to_string()), cx);
|
||||||
|
assert!(editor.completion_state.is_none());
|
||||||
|
editor.handle_input(&Input("s".to_string()), cx);
|
||||||
|
assert!(editor.completion_state.is_none());
|
||||||
|
});
|
||||||
|
|
||||||
|
handle_completion_request(
|
||||||
|
&mut fake,
|
||||||
|
"/the/file",
|
||||||
|
Point::new(2, 7),
|
||||||
|
&[
|
||||||
|
(Point::new(2, 6)..Point::new(2, 7), "fourth_completion"),
|
||||||
|
(Point::new(2, 6)..Point::new(2, 7), "fifth_completion"),
|
||||||
|
(Point::new(2, 6)..Point::new(2, 7), "sixth_completion"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
editor
|
||||||
|
.condition(&cx, |editor, _| editor.completion_state.is_some())
|
||||||
|
.await;
|
||||||
|
|
||||||
|
editor.update(&mut cx, |editor, cx| {
|
||||||
|
editor.handle_input(&Input("i".to_string()), cx);
|
||||||
|
});
|
||||||
|
|
||||||
|
handle_completion_request(
|
||||||
|
&mut fake,
|
||||||
|
"/the/file",
|
||||||
|
Point::new(2, 8),
|
||||||
|
&[
|
||||||
|
(Point::new(2, 6)..Point::new(2, 8), "fourth_completion"),
|
||||||
|
(Point::new(2, 6)..Point::new(2, 8), "fifth_completion"),
|
||||||
|
(Point::new(2, 6)..Point::new(2, 8), "sixth_completion"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
editor.next_notification(&cx).await;
|
||||||
|
|
||||||
|
let apply_additional_edits = editor.update(&mut cx, |editor, cx| {
|
||||||
|
let apply_additional_edits = editor.confirm_completion(None, cx).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
editor.text(cx),
|
||||||
|
"
|
||||||
|
one.second_completion
|
||||||
|
two sixth_completion
|
||||||
|
three sixth_completion
|
||||||
|
additional edit
|
||||||
|
"
|
||||||
|
.unindent()
|
||||||
|
);
|
||||||
|
apply_additional_edits
|
||||||
|
});
|
||||||
|
handle_resolve_completion_request(&mut fake, None).await;
|
||||||
|
apply_additional_edits.await.unwrap();
|
||||||
|
|
||||||
async fn handle_completion_request(
|
async fn handle_completion_request(
|
||||||
fake: &mut FakeLanguageServer,
|
fake: &mut FakeLanguageServer,
|
||||||
path: &str,
|
path: &str,
|
||||||
|
@ -7208,6 +7266,7 @@ mod tests {
|
||||||
let completions = completions
|
let completions = completions
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(range, new_text)| lsp::CompletionItem {
|
.map(|(range, new_text)| lsp::CompletionItem {
|
||||||
|
label: new_text.to_string(),
|
||||||
text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
|
text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
|
||||||
range: lsp::Range::new(
|
range: lsp::Range::new(
|
||||||
lsp::Position::new(range.start.row, range.start.column),
|
lsp::Position::new(range.start.row, range.start.column),
|
||||||
|
|
|
@ -236,16 +236,14 @@ impl Deterministic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_on(&self, future: &mut AnyLocalFuture) -> Option<Box<dyn Any>> {
|
fn block<F, T>(&self, future: &mut F, max_ticks: usize) -> Option<T>
|
||||||
|
where
|
||||||
|
F: Unpin + Future<Output = T>,
|
||||||
|
{
|
||||||
let unparker = self.parker.lock().unparker();
|
let unparker = self.parker.lock().unparker();
|
||||||
let waker = waker_fn(move || {
|
let waker = waker_fn(move || {
|
||||||
unparker.unpark();
|
unparker.unpark();
|
||||||
});
|
});
|
||||||
let max_ticks = {
|
|
||||||
let mut state = self.state.lock();
|
|
||||||
let range = state.block_on_ticks.clone();
|
|
||||||
state.rng.gen_range(range)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut cx = Context::from_waker(&waker);
|
let mut cx = Context::from_waker(&waker);
|
||||||
for _ in 0..max_ticks {
|
for _ in 0..max_ticks {
|
||||||
|
@ -258,7 +256,7 @@ impl Deterministic {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
} else {
|
} else {
|
||||||
drop(state);
|
drop(state);
|
||||||
if let Poll::Ready(result) = future.as_mut().poll(&mut cx) {
|
if let Poll::Ready(result) = future.poll(&mut cx) {
|
||||||
return Some(result);
|
return Some(result);
|
||||||
}
|
}
|
||||||
let mut state = self.state.lock();
|
let mut state = self.state.lock();
|
||||||
|
@ -488,6 +486,19 @@ impl Background {
|
||||||
Task::send(any_task)
|
Task::send(any_task)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn block<F, T>(&self, future: F) -> T
|
||||||
|
where
|
||||||
|
F: Future<Output = T>,
|
||||||
|
{
|
||||||
|
smol::pin!(future);
|
||||||
|
match self {
|
||||||
|
Self::Production { .. } => smol::block_on(&mut future),
|
||||||
|
Self::Deterministic { executor, .. } => {
|
||||||
|
executor.block(&mut future, usize::MAX).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn block_with_timeout<F, T>(
|
pub fn block_with_timeout<F, T>(
|
||||||
&self,
|
&self,
|
||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
|
@ -501,7 +512,14 @@ impl Background {
|
||||||
if !timeout.is_zero() {
|
if !timeout.is_zero() {
|
||||||
let output = match self {
|
let output = match self {
|
||||||
Self::Production { .. } => smol::block_on(util::timeout(timeout, &mut future)).ok(),
|
Self::Production { .. } => smol::block_on(util::timeout(timeout, &mut future)).ok(),
|
||||||
Self::Deterministic { executor, .. } => executor.block_on(&mut future),
|
Self::Deterministic { executor, .. } => {
|
||||||
|
let max_ticks = {
|
||||||
|
let mut state = executor.state.lock();
|
||||||
|
let range = state.block_on_ticks.clone();
|
||||||
|
state.rng.gen_range(range)
|
||||||
|
};
|
||||||
|
executor.block(&mut future, max_ticks)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
if let Some(output) = output {
|
if let Some(output) = output {
|
||||||
return Ok(*output.downcast().unwrap());
|
return Ok(*output.downcast().unwrap());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue