windows: Get more tests passing (#39984)

Still got one more test in `project_tests.rs` to investigate...

Release Notes:

- N/A

---------

Co-authored-by: John Tur <john-tur@outlook.com>
This commit is contained in:
Jakub Konka
2025-10-12 18:13:40 +02:00
committed by GitHub
co-authored by John Tur
parent 998fece3af
commit bbb6783fb8
5 changed files with 138 additions and 20 deletions
+119 -9
View File
@@ -1,5 +1,5 @@
use crate::{
AnchorRangeExt, DisplayPoint, Editor, MultiBuffer, RowExt,
AnchorRangeExt, DisplayPoint, Editor, ExcerptId, MultiBuffer, MultiBufferSnapshot, RowExt,
display_map::{HighlightKey, ToDisplayPoint},
};
use buffer_diff::DiffHunkStatusKind;
@@ -24,6 +24,7 @@ use std::{
atomic::{AtomicUsize, Ordering},
},
};
use text::Selection;
use util::{
assert_set_eq,
test::{generate_marked_text, marked_text_ranges},
@@ -388,6 +389,23 @@ impl EditorTestContext {
#[track_caller]
pub fn assert_excerpts_with_selections(&mut self, marked_text: &str) {
let actual_text = self.to_format_multibuffer_as_marked_text();
let fmt_additional_notes = || {
struct Format<'a, T: std::fmt::Display>(&'a str, &'a T);
impl<T: std::fmt::Display> std::fmt::Display for Format<'_, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"\n\n----- EXPECTED: -----\n\n{}\n\n----- ACTUAL: -----\n\n{}\n\n",
self.0, self.1
)
}
}
Format(marked_text, &actual_text)
};
let expected_excerpts = marked_text
.strip_prefix("[EXCERPT]\n")
.unwrap()
@@ -408,9 +426,10 @@ impl EditorTestContext {
assert!(
excerpts.len() == expected_excerpts.len(),
"should have {} excerpts, got {}",
"should have {} excerpts, got {}{}",
expected_excerpts.len(),
excerpts.len()
excerpts.len(),
fmt_additional_notes(),
);
for (ix, (excerpt_id, snapshot, range)) in excerpts.into_iter().enumerate() {
@@ -424,18 +443,25 @@ impl EditorTestContext {
if !expected_selections.is_empty() {
assert!(
is_selected,
"excerpt {ix} should be selected. got {:?}",
"excerpt {ix} should contain selections. got {:?}{}",
self.editor_state(),
fmt_additional_notes(),
);
} else {
assert!(
!is_selected,
"excerpt {ix} should not be selected, got: {selections:?}",
"excerpt {ix} should not contain selections, got: {selections:?}{}",
fmt_additional_notes(),
);
}
continue;
}
assert!(!is_folded, "excerpt {} should not be folded", ix);
assert!(
!is_folded,
"excerpt {} should not be folded{}",
ix,
fmt_additional_notes()
);
assert_eq!(
multibuffer_snapshot
.text_for_range(Anchor::range_in_buffer(
@@ -444,7 +470,9 @@ impl EditorTestContext {
range.context.clone()
))
.collect::<String>(),
expected_text
expected_text,
"{}",
fmt_additional_notes(),
);
let selections = selections
@@ -460,13 +488,38 @@ impl EditorTestContext {
.collect::<Vec<_>>();
// todo: selections that cross excerpt boundaries..
assert_eq!(
selections, expected_selections,
"excerpt {} has incorrect selections",
selections,
expected_selections,
"excerpt {} has incorrect selections{}",
ix,
fmt_additional_notes()
);
}
}
fn to_format_multibuffer_as_marked_text(&mut self) -> FormatMultiBufferAsMarkedText {
let (multibuffer_snapshot, selections, excerpts) = self.update_editor(|editor, _, cx| {
let multibuffer_snapshot = editor.buffer.read(cx).snapshot(cx);
let selections = editor.selections.disjoint_anchors_arc().to_vec();
let excerpts = multibuffer_snapshot
.excerpts()
.map(|(e_id, snapshot, range)| {
let is_folded = editor.is_buffer_folded(snapshot.remote_id(), cx);
(e_id, snapshot.clone(), range, is_folded)
})
.collect::<Vec<_>>();
(multibuffer_snapshot, selections, excerpts)
});
FormatMultiBufferAsMarkedText {
multibuffer_snapshot,
selections,
excerpts,
}
}
/// Make an assertion about the editor's text and the ranges and directions
/// of its selections using a string containing embedded range markers.
///
@@ -571,6 +624,63 @@ impl EditorTestContext {
}
}
struct FormatMultiBufferAsMarkedText {
multibuffer_snapshot: MultiBufferSnapshot,
selections: Vec<Selection<Anchor>>,
excerpts: Vec<(ExcerptId, BufferSnapshot, ExcerptRange<text::Anchor>, bool)>,
}
impl std::fmt::Display for FormatMultiBufferAsMarkedText {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self {
multibuffer_snapshot,
selections,
excerpts,
} = self;
for (excerpt_id, snapshot, range, is_folded) in excerpts.into_iter() {
write!(f, "[EXCERPT]\n")?;
if *is_folded {
write!(f, "[FOLDED]\n")?;
}
let mut text = multibuffer_snapshot
.text_for_range(Anchor::range_in_buffer(
*excerpt_id,
snapshot.remote_id(),
range.context.clone(),
))
.collect::<String>();
let selections = selections
.iter()
.filter(|&s| s.head().excerpt_id == *excerpt_id)
.map(|s| {
let head = text::ToOffset::to_offset(&s.head().text_anchor, &snapshot)
- text::ToOffset::to_offset(&range.context.start, &snapshot);
let tail = text::ToOffset::to_offset(&s.head().text_anchor, &snapshot)
- text::ToOffset::to_offset(&range.context.start, &snapshot);
tail..head
})
.rev()
.collect::<Vec<_>>();
for selection in selections {
if selection.is_empty() {
text.insert(selection.start, 'ˇ');
continue;
}
text.insert(selection.end, '»');
text.insert(selection.start, '«');
}
write!(f, "{text}")?;
}
Ok(())
}
}
#[track_caller]
pub fn assert_state_with_diff(
editor: &Entity<Editor>,
+7 -8
View File
@@ -1619,14 +1619,13 @@ mod tests {
project_diff::{self, ProjectDiff},
};
#[cfg_attr(windows, ignore = "currently fails on windows")]
#[gpui::test]
async fn test_go_to_prev_hunk_multibuffer(cx: &mut TestAppContext) {
init_test(cx);
let fs = FakeFs::new(cx.executor());
fs.insert_tree(
"/a",
path!("/a"),
json!({
".git": {},
"a.txt": "created\n",
@@ -1637,7 +1636,7 @@ mod tests {
.await;
fs.set_head_and_index_for_repo(
Path::new("/a/.git"),
Path::new(path!("/a/.git")),
&[
("b.txt", "before\n".to_string()),
("c.txt", "unchanged\n".to_string()),
@@ -1645,7 +1644,7 @@ mod tests {
],
);
let project = Project::test(fs, [Path::new("/a")], cx).await;
let project = Project::test(fs, [Path::new(path!("/a"))], cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
@@ -1707,7 +1706,6 @@ mod tests {
));
}
#[cfg_attr(windows, ignore = "currently fails on windows")]
#[gpui::test]
async fn test_excerpts_splitting_after_restoring_the_middle_excerpt(cx: &mut TestAppContext) {
init_test(cx);
@@ -1747,7 +1745,7 @@ mod tests {
let fs = FakeFs::new(cx.executor());
fs.insert_tree(
"/a",
path!("/a"),
json!({
".git": {},
"main.rs": buffer_contents,
@@ -1756,11 +1754,11 @@ mod tests {
.await;
fs.set_head_and_index_for_repo(
Path::new("/a/.git"),
Path::new(path!("/a/.git")),
&[("main.rs", git_contents.to_owned())],
);
let project = Project::test(fs, [Path::new("/a")], cx).await;
let project = Project::test(fs, [Path::new(path!("/a"))], cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
@@ -1925,6 +1923,7 @@ mod tests {
cx.run_until_parked();
let editor = diff.read_with(cx, |diff, _| diff.editor.clone());
assert_state_with_diff(
&editor,
cx,
+6 -1
View File
@@ -94,6 +94,9 @@ async fn test_block_via_smol(cx: &mut gpui::TestAppContext) {
task.await;
}
// NOTE:
// While POSIX symbolic links are somewhat supported on Windows, they are an opt in by the user, and thus
// we assume that they are not supported out of the box.
#[cfg(not(windows))]
#[gpui::test]
async fn test_symlinks(cx: &mut gpui::TestAppContext) {
@@ -8536,6 +8539,7 @@ async fn test_update_gitignore(cx: &mut gpui::TestAppContext) {
// a directory which some program has already open.
// This is a limitation of the Windows.
// See: https://stackoverflow.com/questions/41365318/access-is-denied-when-renaming-folder
// See: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_file_rename_information
#[gpui::test]
#[cfg_attr(target_os = "windows", ignore)]
async fn test_rename_work_directory(cx: &mut gpui::TestAppContext) {
@@ -8615,7 +8619,8 @@ async fn test_rename_work_directory(cx: &mut gpui::TestAppContext) {
// NOTE: This test always fails on Windows, because on Windows, unlike on Unix,
// you can't rename a directory which some program has already open. This is a
// limitation of the Windows. See:
// https://stackoverflow.com/questions/41365318/access-is-denied-when-renaming-folder
// See: https://stackoverflow.com/questions/41365318/access-is-denied-when-renaming-folder
// See: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_file_rename_information
#[gpui::test]
#[cfg_attr(target_os = "windows", ignore)]
async fn test_file_status(cx: &mut gpui::TestAppContext) {
@@ -2983,6 +2983,12 @@ async fn test_new_file_move(cx: &mut gpui::TestAppContext) {
);
}
// NOTE: This test is skipped on Windows, because on Windows, unlike on Unix,
// you can't rename a directory which some program has already open. This is a
// limitation of the Windows. Since Zed will have the root open, it will hold an open handle
// to it, and thus renaming it will fail on Windows.
// See: https://stackoverflow.com/questions/41365318/access-is-denied-when-renaming-folder
// See: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_file_rename_information
#[gpui::test]
#[cfg_attr(target_os = "windows", ignore)]
async fn test_rename_root_of_worktree(cx: &mut gpui::TestAppContext) {
@@ -1327,8 +1327,6 @@ async fn test_copy_file_into_remote_project(
);
}
// TODO: this test fails on Windows.
#[cfg(not(windows))]
#[gpui::test]
async fn test_remote_git_diffs(cx: &mut TestAppContext, server_cx: &mut TestAppContext) {
let text_2 = "