windows: Fix tests on Windows (#22616)
Release Notes: - N/A --------- Co-authored-by: Mikayla <mikayla.c.maki@gmail.com>
This commit is contained in:
parent
c252b5db16
commit
74c4dbd237
56 changed files with 1540 additions and 856 deletions
26
.github/actions/run_tests_windows/action.yml
vendored
Normal file
26
.github/actions/run_tests_windows/action.yml
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
name: "Run tests on Windows"
|
||||
description: "Runs the tests on Windows"
|
||||
|
||||
inputs:
|
||||
working-directory:
|
||||
description: "The working directory"
|
||||
required: true
|
||||
default: "."
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Install Rust
|
||||
shell: pwsh
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
run: cargo install cargo-nextest --locked
|
||||
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4
|
||||
with:
|
||||
node-version: "18"
|
||||
|
||||
- name: Run tests
|
||||
shell: pwsh
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
run: cargo nextest run --workspace --no-fail-fast
|
10
.github/workflows/ci.yml
vendored
10
.github/workflows/ci.yml
vendored
|
@ -228,7 +228,6 @@ jobs:
|
|||
if: always()
|
||||
run: rm -rf ./../.cargo
|
||||
|
||||
# todo(windows): Actually run the tests
|
||||
windows_tests:
|
||||
timeout-minutes: 60
|
||||
name: (Windows) Run Clippy and tests
|
||||
|
@ -269,10 +268,19 @@ jobs:
|
|||
# Windows can't run shell scripts, so we need to use `cargo xtask`.
|
||||
run: cargo xtask clippy
|
||||
|
||||
- name: Run tests
|
||||
uses: ./.github/actions/run_tests_windows
|
||||
with:
|
||||
working-directory: ${{ env.ZED_WORKSPACE }}
|
||||
|
||||
- name: Build Zed
|
||||
working-directory: ${{ env.ZED_WORKSPACE }}
|
||||
run: cargo build
|
||||
|
||||
- name: Check dev drive space
|
||||
working-directory: ${{ env.ZED_WORKSPACE }}
|
||||
run: ./script/exit-ci-if-dev-drive-is-full.ps1 55
|
||||
|
||||
# Since the Windows runners are stateful, so we need to remove the config file to prevent potential bug.
|
||||
- name: Clean CI config file
|
||||
if: always()
|
||||
|
|
9
Cargo.lock
generated
9
Cargo.lock
generated
|
@ -14404,6 +14404,15 @@ dependencies = [
|
|||
"tempfile",
|
||||
"tendril",
|
||||
"unicase",
|
||||
"util_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "util_macros"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
13
Cargo.toml
13
Cargo.toml
|
@ -144,6 +144,7 @@ members = [
|
|||
"crates/ui_input",
|
||||
"crates/ui_macros",
|
||||
"crates/util",
|
||||
"crates/util_macros",
|
||||
"crates/vcs_menu",
|
||||
"crates/vim",
|
||||
"crates/vim_mode_setting",
|
||||
|
@ -339,6 +340,7 @@ ui = { path = "crates/ui" }
|
|||
ui_input = { path = "crates/ui_input" }
|
||||
ui_macros = { path = "crates/ui_macros" }
|
||||
util = { path = "crates/util" }
|
||||
util_macros = { path = "crates/util_macros" }
|
||||
vcs_menu = { path = "crates/vcs_menu" }
|
||||
vim = { path = "crates/vim" }
|
||||
vim_mode_setting = { path = "crates/vim_mode_setting" }
|
||||
|
@ -359,7 +361,7 @@ alacritty_terminal = { git = "https://github.com/alacritty/alacritty.git", rev =
|
|||
any_vec = "0.14"
|
||||
anyhow = "1.0.86"
|
||||
arrayvec = { version = "0.7.4", features = ["serde"] }
|
||||
ashpd = { version = "0.10", default-features = false, features = ["async-std"]}
|
||||
ashpd = { version = "0.10", default-features = false, features = ["async-std"] }
|
||||
async-compat = "0.2.1"
|
||||
async-compression = { version = "0.4", features = ["gzip", "futures-io"] }
|
||||
async-dispatcher = "0.1"
|
||||
|
@ -421,7 +423,11 @@ jupyter-websocket-client = { version = "0.9.0" }
|
|||
libc = "0.2"
|
||||
libsqlite3-sys = { version = "0.30.1", features = ["bundled"] }
|
||||
linkify = "0.10.0"
|
||||
livekit = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev="811ceae29fabee455f110c56cd66b3f49a7e5003", features = ["dispatcher", "services-dispatcher", "rustls-tls-native-roots"], default-features = false }
|
||||
livekit = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "811ceae29fabee455f110c56cd66b3f49a7e5003", features = [
|
||||
"dispatcher",
|
||||
"services-dispatcher",
|
||||
"rustls-tls-native-roots",
|
||||
], default-features = false }
|
||||
log = { version = "0.4.16", features = ["kv_unstable_serde", "serde"] }
|
||||
markup5ever_rcdom = "0.3.0"
|
||||
nanoid = "0.4"
|
||||
|
@ -441,11 +447,13 @@ pet-poetry = { git = "https://github.com/microsoft/python-environment-tools.git"
|
|||
pet-reporter = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0" }
|
||||
postage = { version = "0.5", features = ["futures-traits"] }
|
||||
pretty_assertions = { version = "1.3.0", features = ["unstable"] }
|
||||
proc-macro2 = "1.0.93"
|
||||
profiling = "1"
|
||||
prost = "0.9"
|
||||
prost-build = "0.9"
|
||||
prost-types = "0.9"
|
||||
pulldown-cmark = { version = "0.12.0", default-features = false }
|
||||
quote = "1.0.9"
|
||||
rand = "0.8.5"
|
||||
rayon = "1.8"
|
||||
regex = "1.5"
|
||||
|
@ -489,6 +497,7 @@ sqlformat = "0.2"
|
|||
strsim = "0.11"
|
||||
strum = { version = "0.26.0", features = ["derive"] }
|
||||
subtle = "2.5.0"
|
||||
syn = { version = "1.0.72", features = ["full", "extra-traits"] }
|
||||
sys-locale = "0.3.1"
|
||||
sysinfo = "0.31.0"
|
||||
take-until = "0.2.0"
|
||||
|
|
|
@ -323,7 +323,14 @@ fn collect_files(
|
|||
)))?;
|
||||
directory_stack.push(entry.path.clone());
|
||||
} else {
|
||||
let entry_name = format!("{}/{}", prefix_paths, &filename);
|
||||
// todo(windows)
|
||||
// Potential bug: this assumes that the path separator is always `\` on Windows
|
||||
let entry_name = format!(
|
||||
"{}{}{}",
|
||||
prefix_paths,
|
||||
std::path::MAIN_SEPARATOR_STR,
|
||||
&filename
|
||||
);
|
||||
events_tx.unbounded_send(Ok(SlashCommandEvent::StartSection {
|
||||
icon: IconName::Folder,
|
||||
label: entry_name.clone().into(),
|
||||
|
@ -455,6 +462,7 @@ mod custom_path_matcher {
|
|||
use std::{fmt::Debug as _, path::Path};
|
||||
|
||||
use globset::{Glob, GlobSet, GlobSetBuilder};
|
||||
use util::paths::SanitizedPath;
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct PathMatcher {
|
||||
|
@ -481,7 +489,7 @@ mod custom_path_matcher {
|
|||
pub fn new(globs: &[String]) -> Result<Self, globset::Error> {
|
||||
let globs = globs
|
||||
.into_iter()
|
||||
.map(|glob| Glob::new(&glob))
|
||||
.map(|glob| Glob::new(&SanitizedPath::from(glob).to_glob_string()))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let sources = globs.iter().map(|glob| glob.glob().to_owned()).collect();
|
||||
let sources_with_trailing_slash = globs
|
||||
|
@ -507,7 +515,9 @@ mod custom_path_matcher {
|
|||
.zip(self.sources_with_trailing_slash.iter())
|
||||
.any(|(source, with_slash)| {
|
||||
let as_bytes = other_path.as_os_str().as_encoded_bytes();
|
||||
let with_slash = if source.ends_with("/") {
|
||||
// todo(windows)
|
||||
// Potential bug: this assumes that the path separator is always `\` on Windows
|
||||
let with_slash = if source.ends_with(std::path::MAIN_SEPARATOR_STR) {
|
||||
source.as_bytes()
|
||||
} else {
|
||||
with_slash.as_bytes()
|
||||
|
@ -569,6 +579,7 @@ mod test {
|
|||
use serde_json::json;
|
||||
use settings::SettingsStore;
|
||||
use smol::stream::StreamExt;
|
||||
use util::{path, separator};
|
||||
|
||||
use super::collect_files;
|
||||
|
||||
|
@ -592,7 +603,7 @@ mod test {
|
|||
let fs = FakeFs::new(cx.executor());
|
||||
|
||||
fs.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
"dir": {
|
||||
"subdir": {
|
||||
|
@ -607,7 +618,7 @@ mod test {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/root").as_ref()], cx).await;
|
||||
|
||||
let result_1 =
|
||||
cx.update(|cx| collect_files(project.clone(), &["root/dir".to_string()], cx));
|
||||
|
@ -615,7 +626,7 @@ mod test {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
assert!(result_1.text.starts_with("root/dir"));
|
||||
assert!(result_1.text.starts_with(separator!("root/dir")));
|
||||
// 4 files + 2 directories
|
||||
assert_eq!(result_1.sections.len(), 6);
|
||||
|
||||
|
@ -631,7 +642,7 @@ mod test {
|
|||
cx.update(|cx| collect_files(project.clone(), &["root/dir*".to_string()], cx).boxed());
|
||||
let result = SlashCommandOutput::from_event_stream(result).await.unwrap();
|
||||
|
||||
assert!(result.text.starts_with("root/dir"));
|
||||
assert!(result.text.starts_with(separator!("root/dir")));
|
||||
// 5 files + 2 directories
|
||||
assert_eq!(result.sections.len(), 7);
|
||||
|
||||
|
@ -645,7 +656,7 @@ mod test {
|
|||
let fs = FakeFs::new(cx.executor());
|
||||
|
||||
fs.insert_tree(
|
||||
"/zed",
|
||||
path!("/zed"),
|
||||
json!({
|
||||
"assets": {
|
||||
"dir1": {
|
||||
|
@ -670,7 +681,7 @@ mod test {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/zed".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/zed").as_ref()], cx).await;
|
||||
|
||||
let result =
|
||||
cx.update(|cx| collect_files(project.clone(), &["zed/assets/themes".to_string()], cx));
|
||||
|
@ -679,27 +690,36 @@ mod test {
|
|||
.unwrap();
|
||||
|
||||
// Sanity check
|
||||
assert!(result.text.starts_with("zed/assets/themes\n"));
|
||||
assert!(result.text.starts_with(separator!("zed/assets/themes\n")));
|
||||
assert_eq!(result.sections.len(), 7);
|
||||
|
||||
// Ensure that full file paths are included in the real output
|
||||
assert!(result.text.contains("zed/assets/themes/andromeda/LICENSE"));
|
||||
assert!(result.text.contains("zed/assets/themes/ayu/LICENSE"));
|
||||
assert!(result.text.contains("zed/assets/themes/summercamp/LICENSE"));
|
||||
assert!(result
|
||||
.text
|
||||
.contains(separator!("zed/assets/themes/andromeda/LICENSE")));
|
||||
assert!(result
|
||||
.text
|
||||
.contains(separator!("zed/assets/themes/ayu/LICENSE")));
|
||||
assert!(result
|
||||
.text
|
||||
.contains(separator!("zed/assets/themes/summercamp/LICENSE")));
|
||||
|
||||
assert_eq!(result.sections[5].label, "summercamp");
|
||||
|
||||
// Ensure that things are in descending order, with properly relativized paths
|
||||
assert_eq!(
|
||||
result.sections[0].label,
|
||||
"zed/assets/themes/andromeda/LICENSE"
|
||||
separator!("zed/assets/themes/andromeda/LICENSE")
|
||||
);
|
||||
assert_eq!(result.sections[1].label, "andromeda");
|
||||
assert_eq!(result.sections[2].label, "zed/assets/themes/ayu/LICENSE");
|
||||
assert_eq!(
|
||||
result.sections[2].label,
|
||||
separator!("zed/assets/themes/ayu/LICENSE")
|
||||
);
|
||||
assert_eq!(result.sections[3].label, "ayu");
|
||||
assert_eq!(
|
||||
result.sections[4].label,
|
||||
"zed/assets/themes/summercamp/LICENSE"
|
||||
separator!("zed/assets/themes/summercamp/LICENSE")
|
||||
);
|
||||
|
||||
// Ensure that the project lasts until after the last await
|
||||
|
@ -712,7 +732,7 @@ mod test {
|
|||
let fs = FakeFs::new(cx.executor());
|
||||
|
||||
fs.insert_tree(
|
||||
"/zed",
|
||||
path!("/zed"),
|
||||
json!({
|
||||
"assets": {
|
||||
"themes": {
|
||||
|
@ -732,7 +752,7 @@ mod test {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/zed".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/zed").as_ref()], cx).await;
|
||||
|
||||
let result =
|
||||
cx.update(|cx| collect_files(project.clone(), &["zed/assets/themes".to_string()], cx));
|
||||
|
@ -740,26 +760,29 @@ mod test {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
assert!(result.text.starts_with("zed/assets/themes\n"));
|
||||
assert_eq!(result.sections[0].label, "zed/assets/themes/LICENSE");
|
||||
assert!(result.text.starts_with(separator!("zed/assets/themes\n")));
|
||||
assert_eq!(
|
||||
result.sections[0].label,
|
||||
separator!("zed/assets/themes/LICENSE")
|
||||
);
|
||||
assert_eq!(
|
||||
result.sections[1].label,
|
||||
"zed/assets/themes/summercamp/LICENSE"
|
||||
separator!("zed/assets/themes/summercamp/LICENSE")
|
||||
);
|
||||
assert_eq!(
|
||||
result.sections[2].label,
|
||||
"zed/assets/themes/summercamp/subdir/LICENSE"
|
||||
separator!("zed/assets/themes/summercamp/subdir/LICENSE")
|
||||
);
|
||||
assert_eq!(
|
||||
result.sections[3].label,
|
||||
"zed/assets/themes/summercamp/subdir/subsubdir/LICENSE"
|
||||
separator!("zed/assets/themes/summercamp/subdir/subsubdir/LICENSE")
|
||||
);
|
||||
assert_eq!(result.sections[4].label, "subsubdir");
|
||||
assert_eq!(result.sections[5].label, "subdir");
|
||||
assert_eq!(result.sections[6].label, "summercamp");
|
||||
assert_eq!(result.sections[7].label, "zed/assets/themes");
|
||||
assert_eq!(result.sections[7].label, separator!("zed/assets/themes"));
|
||||
|
||||
assert_eq!(result.text, "zed/assets/themes\n```zed/assets/themes/LICENSE\n1\n```\n\nsummercamp\n```zed/assets/themes/summercamp/LICENSE\n1\n```\n\nsubdir\n```zed/assets/themes/summercamp/subdir/LICENSE\n1\n```\n\nsubsubdir\n```zed/assets/themes/summercamp/subdir/subsubdir/LICENSE\n3\n```\n\n");
|
||||
assert_eq!(result.text, separator!("zed/assets/themes\n```zed/assets/themes/LICENSE\n1\n```\n\nsummercamp\n```zed/assets/themes/summercamp/LICENSE\n1\n```\n\nsubdir\n```zed/assets/themes/summercamp/subdir/LICENSE\n1\n```\n\nsubsubdir\n```zed/assets/themes/summercamp/subdir/subsubdir/LICENSE\n3\n```\n\n"));
|
||||
|
||||
// Ensure that the project lasts until after the last await
|
||||
drop(project);
|
||||
|
|
|
@ -1061,6 +1061,7 @@ async fn get_copilot_lsp(http: Arc<dyn HttpClient>) -> anyhow::Result<PathBuf> {
|
|||
mod tests {
|
||||
use super::*;
|
||||
use gpui::TestAppContext;
|
||||
use util::path;
|
||||
|
||||
#[gpui::test(iterations = 10)]
|
||||
async fn test_buffer_management(cx: &mut TestAppContext) {
|
||||
|
@ -1123,7 +1124,7 @@ mod tests {
|
|||
buffer_1.update(cx, |buffer, cx| {
|
||||
buffer.file_updated(
|
||||
Arc::new(File {
|
||||
abs_path: "/root/child/buffer-1".into(),
|
||||
abs_path: path!("/root/child/buffer-1").into(),
|
||||
path: Path::new("child/buffer-1").into(),
|
||||
}),
|
||||
cx,
|
||||
|
@ -1136,7 +1137,7 @@ mod tests {
|
|||
text_document: lsp::TextDocumentIdentifier::new(buffer_1_uri),
|
||||
}
|
||||
);
|
||||
let buffer_1_uri = lsp::Url::from_file_path("/root/child/buffer-1").unwrap();
|
||||
let buffer_1_uri = lsp::Url::from_file_path(path!("/root/child/buffer-1")).unwrap();
|
||||
assert_eq!(
|
||||
lsp.receive_notification::<lsp::notification::DidOpenTextDocument>()
|
||||
.await,
|
||||
|
|
|
@ -290,7 +290,10 @@ mod tests {
|
|||
use serde_json::json;
|
||||
use settings::SettingsStore;
|
||||
use std::future::Future;
|
||||
use util::test::{marked_text_ranges_by, TextRangeMarker};
|
||||
use util::{
|
||||
path,
|
||||
test::{marked_text_ranges_by, TextRangeMarker},
|
||||
};
|
||||
|
||||
#[gpui::test(iterations = 10)]
|
||||
async fn test_copilot(executor: BackgroundExecutor, cx: &mut TestAppContext) {
|
||||
|
@ -949,24 +952,24 @@ mod tests {
|
|||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
"/test",
|
||||
path!("/test"),
|
||||
json!({
|
||||
".env": "SECRET=something\n",
|
||||
"README.md": "hello\nworld\nhow\nare\nyou\ntoday"
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
let project = Project::test(fs, ["/test".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/test").as_ref()], cx).await;
|
||||
|
||||
let private_buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/test/.env", cx)
|
||||
project.open_local_buffer(path!("/test/.env"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
let public_buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/test/README.md", cx)
|
||||
project.open_local_buffer(path!("/test/README.md"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
|
@ -1433,7 +1433,10 @@ impl ToDisplayPoint for Anchor {
|
|||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use super::*;
|
||||
use crate::{movement, test::marked_display_snapshot};
|
||||
use crate::{
|
||||
movement,
|
||||
test::{marked_display_snapshot, test_font},
|
||||
};
|
||||
use block_map::BlockPlacement;
|
||||
use gpui::{
|
||||
div, font, observe, px, App, AppContext as _, BorrowAppContext, Element, Hsla, Rgba,
|
||||
|
@ -1492,10 +1495,11 @@ pub mod tests {
|
|||
}
|
||||
});
|
||||
|
||||
let font = test_font();
|
||||
let map = cx.new(|cx| {
|
||||
DisplayMap::new(
|
||||
buffer.clone(),
|
||||
font("Helvetica"),
|
||||
font,
|
||||
font_size,
|
||||
wrap_width,
|
||||
true,
|
||||
|
|
|
@ -1992,8 +1992,9 @@ fn offset_for_row(s: &str, target: u32) -> (u32, usize) {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::display_map::{
|
||||
fold_map::FoldMap, inlay_map::InlayMap, tab_map::TabMap, wrap_map::WrapMap,
|
||||
use crate::{
|
||||
display_map::{fold_map::FoldMap, inlay_map::InlayMap, tab_map::TabMap, wrap_map::WrapMap},
|
||||
test::test_font,
|
||||
};
|
||||
use gpui::{div, font, px, App, AppContext as _, Element};
|
||||
use itertools::Itertools;
|
||||
|
@ -2227,7 +2228,7 @@ mod tests {
|
|||
multi_buffer
|
||||
});
|
||||
|
||||
let font = font("Helvetica");
|
||||
let font = test_font();
|
||||
let font_size = px(14.);
|
||||
let font_id = cx.text_system().resolve_font(&font);
|
||||
let mut wrap_width = px(0.);
|
||||
|
@ -3069,8 +3070,9 @@ mod tests {
|
|||
let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
|
||||
let (mut fold_map, fold_snapshot) = FoldMap::new(inlay_snapshot);
|
||||
let (mut tab_map, tab_snapshot) = TabMap::new(fold_snapshot, 4.try_into().unwrap());
|
||||
let (wrap_map, wraps_snapshot) = cx
|
||||
.update(|cx| WrapMap::new(tab_snapshot, font("Helvetica"), font_size, wrap_width, cx));
|
||||
let font = test_font();
|
||||
let (wrap_map, wraps_snapshot) =
|
||||
cx.update(|cx| WrapMap::new(tab_snapshot, font, font_size, wrap_width, cx));
|
||||
let mut block_map = BlockMap::new(
|
||||
wraps_snapshot,
|
||||
true,
|
||||
|
|
|
@ -1169,9 +1169,10 @@ mod tests {
|
|||
use super::*;
|
||||
use crate::{
|
||||
display_map::{fold_map::FoldMap, inlay_map::InlayMap, tab_map::TabMap},
|
||||
test::test_font,
|
||||
MultiBuffer,
|
||||
};
|
||||
use gpui::{font, px, test::observe};
|
||||
use gpui::{px, test::observe};
|
||||
use rand::prelude::*;
|
||||
use settings::SettingsStore;
|
||||
use smol::stream::StreamExt;
|
||||
|
@ -1196,7 +1197,8 @@ mod tests {
|
|||
Some(px(rng.gen_range(0.0..=1000.0)))
|
||||
};
|
||||
let tab_size = NonZeroU32::new(rng.gen_range(1..=4)).unwrap();
|
||||
let font = font("Helvetica");
|
||||
|
||||
let font = test_font();
|
||||
let _font_id = text_system.font_id(&font);
|
||||
let font_size = px(14.0);
|
||||
|
||||
|
|
|
@ -40,8 +40,9 @@ use std::{
|
|||
use test::{build_editor_with_project, editor_lsp_test_context::rust_lang};
|
||||
use unindent::Unindent;
|
||||
use util::{
|
||||
assert_set_eq,
|
||||
assert_set_eq, path,
|
||||
test::{marked_text_ranges, marked_text_ranges_by, sample_text, TextRangeMarker},
|
||||
uri,
|
||||
};
|
||||
use workspace::{
|
||||
item::{FollowEvent, FollowableItem, Item, ItemHandle},
|
||||
|
@ -7074,9 +7075,9 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) {
|
|||
init_test(cx, |_| {});
|
||||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_file("/file.rs", Default::default()).await;
|
||||
fs.insert_file(path!("/file.rs"), Default::default()).await;
|
||||
|
||||
let project = Project::test(fs, ["/file.rs".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/file.rs").as_ref()], cx).await;
|
||||
|
||||
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
|
||||
language_registry.add(rust_lang());
|
||||
|
@ -7092,7 +7093,9 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) {
|
|||
);
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| project.open_local_buffer("/file.rs", cx))
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer(path!("/file.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
@ -7117,7 +7120,7 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) {
|
|||
.handle_request::<lsp::request::Formatting, _, _>(move |params, _| async move {
|
||||
assert_eq!(
|
||||
params.text_document.uri,
|
||||
lsp::Url::from_file_path("/file.rs").unwrap()
|
||||
lsp::Url::from_file_path(path!("/file.rs")).unwrap()
|
||||
);
|
||||
assert_eq!(params.options.tab_size, 4);
|
||||
Ok(Some(vec![lsp::TextEdit::new(
|
||||
|
@ -7145,7 +7148,7 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) {
|
|||
fake_server.handle_request::<lsp::request::Formatting, _, _>(move |params, _| async move {
|
||||
assert_eq!(
|
||||
params.text_document.uri,
|
||||
lsp::Url::from_file_path("/file.rs").unwrap()
|
||||
lsp::Url::from_file_path(path!("/file.rs")).unwrap()
|
||||
);
|
||||
futures::future::pending::<()>().await;
|
||||
unreachable!()
|
||||
|
@ -7202,7 +7205,7 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) {
|
|||
.handle_request::<lsp::request::Formatting, _, _>(move |params, _| async move {
|
||||
assert_eq!(
|
||||
params.text_document.uri,
|
||||
lsp::Url::from_file_path("/file.rs").unwrap()
|
||||
lsp::Url::from_file_path(path!("/file.rs")).unwrap()
|
||||
);
|
||||
assert_eq!(params.options.tab_size, 8);
|
||||
Ok(Some(vec![]))
|
||||
|
@ -7237,7 +7240,7 @@ async fn test_multibuffer_format_during_save(cx: &mut gpui::TestAppContext) {
|
|||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
"/a",
|
||||
path!("/a"),
|
||||
json!({
|
||||
"main.rs": sample_text_1,
|
||||
"other.rs": sample_text_2,
|
||||
|
@ -7246,7 +7249,7 @@ async fn test_multibuffer_format_during_save(cx: &mut gpui::TestAppContext) {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/a".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/a").as_ref()], cx).await;
|
||||
let workspace = cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
let cx = &mut VisualTestContext::from_window(*workspace.deref(), cx);
|
||||
|
||||
|
@ -7421,20 +7424,20 @@ async fn test_multibuffer_format_during_save(cx: &mut gpui::TestAppContext) {
|
|||
assert!(cx.read(|cx| !multi_buffer_editor.is_dirty(cx)));
|
||||
assert_eq!(
|
||||
multi_buffer_editor.update(cx, |editor, cx| editor.text(cx)),
|
||||
"a|o[file:///a/main.rs formatted]bbbb\ncccc\n\nffff\ngggg\n\njjjj\n\nlll[file:///a/other.rs formatted]mmmm\nnnnn|four|five|six|\nr\n\nuuuu\n\nvvvv\nwwww\nxxxx\n\n{{{{\n||||\n\n\u{7f}\u{7f}\u{7f}\u{7f}",
|
||||
uri!("a|o[file:///a/main.rs formatted]bbbb\ncccc\n\nffff\ngggg\n\njjjj\n\nlll[file:///a/other.rs formatted]mmmm\nnnnn|four|five|six|\nr\n\nuuuu\n\nvvvv\nwwww\nxxxx\n\n{{{{\n||||\n\n\u{7f}\u{7f}\u{7f}\u{7f}"),
|
||||
);
|
||||
buffer_1.update(cx, |buffer, _| {
|
||||
assert!(!buffer.is_dirty());
|
||||
assert_eq!(
|
||||
buffer.text(),
|
||||
"a|o[file:///a/main.rs formatted]bbbb\ncccc\ndddd\neeee\nffff\ngggg\nhhhh\niiii\njjjj\n",
|
||||
uri!("a|o[file:///a/main.rs formatted]bbbb\ncccc\ndddd\neeee\nffff\ngggg\nhhhh\niiii\njjjj\n"),
|
||||
)
|
||||
});
|
||||
buffer_2.update(cx, |buffer, _| {
|
||||
assert!(!buffer.is_dirty());
|
||||
assert_eq!(
|
||||
buffer.text(),
|
||||
"lll[file:///a/other.rs formatted]mmmm\nnnnn|four|five|six|oooo\npppp\nr\nssss\ntttt\nuuuu\n",
|
||||
uri!("lll[file:///a/other.rs formatted]mmmm\nnnnn|four|five|six|oooo\npppp\nr\nssss\ntttt\nuuuu\n"),
|
||||
)
|
||||
});
|
||||
buffer_3.update(cx, |buffer, _| {
|
||||
|
@ -7448,9 +7451,9 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) {
|
|||
init_test(cx, |_| {});
|
||||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_file("/file.rs", Default::default()).await;
|
||||
fs.insert_file(path!("/file.rs"), Default::default()).await;
|
||||
|
||||
let project = Project::test(fs, ["/file.rs".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/").as_ref()], cx).await;
|
||||
|
||||
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
|
||||
language_registry.add(rust_lang());
|
||||
|
@ -7466,7 +7469,9 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) {
|
|||
);
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| project.open_local_buffer("/file.rs", cx))
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer(path!("/file.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
@ -7491,7 +7496,7 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) {
|
|||
.handle_request::<lsp::request::RangeFormatting, _, _>(move |params, _| async move {
|
||||
assert_eq!(
|
||||
params.text_document.uri,
|
||||
lsp::Url::from_file_path("/file.rs").unwrap()
|
||||
lsp::Url::from_file_path(path!("/file.rs")).unwrap()
|
||||
);
|
||||
assert_eq!(params.options.tab_size, 4);
|
||||
Ok(Some(vec![lsp::TextEdit::new(
|
||||
|
@ -7519,7 +7524,7 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) {
|
|||
move |params, _| async move {
|
||||
assert_eq!(
|
||||
params.text_document.uri,
|
||||
lsp::Url::from_file_path("/file.rs").unwrap()
|
||||
lsp::Url::from_file_path(path!("/file.rs")).unwrap()
|
||||
);
|
||||
futures::future::pending::<()>().await;
|
||||
unreachable!()
|
||||
|
@ -7577,7 +7582,7 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) {
|
|||
.handle_request::<lsp::request::RangeFormatting, _, _>(move |params, _| async move {
|
||||
assert_eq!(
|
||||
params.text_document.uri,
|
||||
lsp::Url::from_file_path("/file.rs").unwrap()
|
||||
lsp::Url::from_file_path(path!("/file.rs")).unwrap()
|
||||
);
|
||||
assert_eq!(params.options.tab_size, 8);
|
||||
Ok(Some(vec![]))
|
||||
|
@ -7597,9 +7602,9 @@ async fn test_document_format_manual_trigger(cx: &mut gpui::TestAppContext) {
|
|||
});
|
||||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_file("/file.rs", Default::default()).await;
|
||||
fs.insert_file(path!("/file.rs"), Default::default()).await;
|
||||
|
||||
let project = Project::test(fs, ["/file.rs".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/").as_ref()], cx).await;
|
||||
|
||||
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
|
||||
language_registry.add(Arc::new(Language::new(
|
||||
|
@ -7633,7 +7638,9 @@ async fn test_document_format_manual_trigger(cx: &mut gpui::TestAppContext) {
|
|||
);
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| project.open_local_buffer("/file.rs", cx))
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer(path!("/file.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
@ -7663,7 +7670,7 @@ async fn test_document_format_manual_trigger(cx: &mut gpui::TestAppContext) {
|
|||
.handle_request::<lsp::request::Formatting, _, _>(move |params, _| async move {
|
||||
assert_eq!(
|
||||
params.text_document.uri,
|
||||
lsp::Url::from_file_path("/file.rs").unwrap()
|
||||
lsp::Url::from_file_path(path!("/file.rs")).unwrap()
|
||||
);
|
||||
assert_eq!(params.options.tab_size, 4);
|
||||
Ok(Some(vec![lsp::TextEdit::new(
|
||||
|
@ -7687,7 +7694,7 @@ async fn test_document_format_manual_trigger(cx: &mut gpui::TestAppContext) {
|
|||
fake_server.handle_request::<lsp::request::Formatting, _, _>(move |params, _| async move {
|
||||
assert_eq!(
|
||||
params.text_document.uri,
|
||||
lsp::Url::from_file_path("/file.rs").unwrap()
|
||||
lsp::Url::from_file_path(path!("/file.rs")).unwrap()
|
||||
);
|
||||
futures::future::pending::<()>().await;
|
||||
unreachable!()
|
||||
|
@ -8727,14 +8734,14 @@ async fn test_multiline_completion(cx: &mut gpui::TestAppContext) {
|
|||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
"/a",
|
||||
path!("/a"),
|
||||
json!({
|
||||
"main.ts": "a",
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/a".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/a").as_ref()], cx).await;
|
||||
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
|
||||
let typescript_language = Arc::new(Language::new(
|
||||
LanguageConfig {
|
||||
|
@ -8794,7 +8801,7 @@ async fn test_multiline_completion(cx: &mut gpui::TestAppContext) {
|
|||
.unwrap();
|
||||
let _buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp("/a/main.ts", cx)
|
||||
project.open_local_buffer_with_lsp(path!("/a/main.ts"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -10570,7 +10577,7 @@ async fn go_to_prev_overlapping_diagnostic(
|
|||
.update_diagnostics(
|
||||
LanguageServerId(0),
|
||||
lsp::PublishDiagnosticsParams {
|
||||
uri: lsp::Url::from_file_path("/root/file").unwrap(),
|
||||
uri: lsp::Url::from_file_path(path!("/root/file")).unwrap(),
|
||||
version: None,
|
||||
diagnostics: vec![
|
||||
lsp::Diagnostic {
|
||||
|
@ -10663,7 +10670,7 @@ async fn test_diagnostics_with_links(cx: &mut TestAppContext) {
|
|||
lsp_store.update_diagnostics(
|
||||
LanguageServerId(0),
|
||||
lsp::PublishDiagnosticsParams {
|
||||
uri: lsp::Url::from_file_path("/root/file").unwrap(),
|
||||
uri: lsp::Url::from_file_path(path!("/root/file")).unwrap(),
|
||||
version: None,
|
||||
diagnostics: vec![lsp::Diagnostic {
|
||||
range: lsp::Range::new(lsp::Position::new(0, 8), lsp::Position::new(0, 12)),
|
||||
|
@ -10923,14 +10930,14 @@ async fn test_on_type_formatting_not_triggered(cx: &mut gpui::TestAppContext) {
|
|||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
"/a",
|
||||
path!("/a"),
|
||||
json!({
|
||||
"main.rs": "fn main() { let a = 5; }",
|
||||
"other.rs": "// Test file",
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
let project = Project::test(fs, ["/a".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/a").as_ref()], cx).await;
|
||||
|
||||
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
|
||||
language_registry.add(Arc::new(Language::new(
|
||||
|
@ -10982,7 +10989,7 @@ async fn test_on_type_formatting_not_triggered(cx: &mut gpui::TestAppContext) {
|
|||
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/a/main.rs", cx)
|
||||
project.open_local_buffer(path!("/a/main.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -11002,7 +11009,7 @@ async fn test_on_type_formatting_not_triggered(cx: &mut gpui::TestAppContext) {
|
|||
fake_server.handle_request::<lsp::request::OnTypeFormatting, _, _>(|params, _| async move {
|
||||
assert_eq!(
|
||||
params.text_document_position.text_document.uri,
|
||||
lsp::Url::from_file_path("/a/main.rs").unwrap(),
|
||||
lsp::Url::from_file_path(path!("/a/main.rs")).unwrap(),
|
||||
);
|
||||
assert_eq!(
|
||||
params.text_document_position.position,
|
||||
|
@ -11040,7 +11047,7 @@ async fn test_language_server_restart_due_to_settings_change(cx: &mut gpui::Test
|
|||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
"/a",
|
||||
path!("/a"),
|
||||
json!({
|
||||
"main.rs": "fn main() { let a = 5; }",
|
||||
"other.rs": "// Test file",
|
||||
|
@ -11048,7 +11055,7 @@ async fn test_language_server_restart_due_to_settings_change(cx: &mut gpui::Test
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/a".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/a").as_ref()], cx).await;
|
||||
|
||||
let server_restarts = Arc::new(AtomicUsize::new(0));
|
||||
let closure_restarts = Arc::clone(&server_restarts);
|
||||
|
@ -11088,7 +11095,7 @@ async fn test_language_server_restart_due_to_settings_change(cx: &mut gpui::Test
|
|||
let _window = cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
let _buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp("/a/main.rs", cx)
|
||||
project.open_local_buffer_with_lsp(path!("/a/main.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -11861,9 +11868,9 @@ async fn test_document_format_with_prettier(cx: &mut gpui::TestAppContext) {
|
|||
});
|
||||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_file("/file.ts", Default::default()).await;
|
||||
fs.insert_file(path!("/file.ts"), Default::default()).await;
|
||||
|
||||
let project = Project::test(fs, ["/file.ts".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/file.ts").as_ref()], cx).await;
|
||||
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
|
||||
|
||||
language_registry.add(Arc::new(Language::new(
|
||||
|
@ -11895,7 +11902,9 @@ async fn test_document_format_with_prettier(cx: &mut gpui::TestAppContext) {
|
|||
|
||||
let prettier_format_suffix = project::TEST_PRETTIER_FORMAT_SUFFIX;
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| project.open_local_buffer("/file.ts", cx))
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer(path!("/file.ts"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
|
|
@ -560,7 +560,7 @@ mod tests {
|
|||
use settings::SettingsStore;
|
||||
use std::{cmp, env, ops::Range, path::Path};
|
||||
use unindent::Unindent as _;
|
||||
use util::RandomCharIter;
|
||||
use util::{path, RandomCharIter};
|
||||
|
||||
// macro_rules! assert_blame_rows {
|
||||
// ($blame:expr, $rows:expr, $expected:expr, $cx:expr) => {
|
||||
|
@ -793,7 +793,7 @@ mod tests {
|
|||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
"/my-repo",
|
||||
path!("/my-repo"),
|
||||
json!({
|
||||
".git": {},
|
||||
"file.txt": r#"
|
||||
|
@ -807,7 +807,7 @@ mod tests {
|
|||
.await;
|
||||
|
||||
fs.set_blame_for_repo(
|
||||
Path::new("/my-repo/.git"),
|
||||
Path::new(path!("/my-repo/.git")),
|
||||
vec![(
|
||||
"file.txt".into(),
|
||||
Blame {
|
||||
|
@ -817,10 +817,10 @@ mod tests {
|
|||
)],
|
||||
);
|
||||
|
||||
let project = Project::test(fs, ["/my-repo".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/my-repo").as_ref()], cx).await;
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/my-repo/file.txt", cx)
|
||||
project.open_local_buffer(path!("/my-repo/file.txt"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -945,7 +945,7 @@ mod tests {
|
|||
log::info!("initial buffer text: {:?}", buffer_initial_text);
|
||||
|
||||
fs.insert_tree(
|
||||
"/my-repo",
|
||||
path!("/my-repo"),
|
||||
json!({
|
||||
".git": {},
|
||||
"file.txt": buffer_initial_text.to_string()
|
||||
|
@ -956,7 +956,7 @@ mod tests {
|
|||
let blame_entries = gen_blame_entries(buffer_initial_text.max_point().row, &mut rng);
|
||||
log::info!("initial blame entries: {:?}", blame_entries);
|
||||
fs.set_blame_for_repo(
|
||||
Path::new("/my-repo/.git"),
|
||||
Path::new(path!("/my-repo/.git")),
|
||||
vec![(
|
||||
"file.txt".into(),
|
||||
Blame {
|
||||
|
@ -966,10 +966,10 @@ mod tests {
|
|||
)],
|
||||
);
|
||||
|
||||
let project = Project::test(fs.clone(), ["/my-repo".as_ref()], cx).await;
|
||||
let project = Project::test(fs.clone(), [path!("/my-repo").as_ref()], cx).await;
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/my-repo/file.txt", cx)
|
||||
project.open_local_buffer(path!("/my-repo/file.txt"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -998,7 +998,7 @@ mod tests {
|
|||
log::info!("regenerating blame entries: {:?}", blame_entries);
|
||||
|
||||
fs.set_blame_for_repo(
|
||||
Path::new("/my-repo/.git"),
|
||||
Path::new(path!("/my-repo/.git")),
|
||||
vec![(
|
||||
"file.txt".into(),
|
||||
Blame {
|
||||
|
|
|
@ -921,7 +921,7 @@ mod tests {
|
|||
use indoc::indoc;
|
||||
use language::language_settings::InlayHintSettings;
|
||||
use lsp::request::{GotoDefinition, GotoTypeDefinition};
|
||||
use util::assert_set_eq;
|
||||
use util::{assert_set_eq, path};
|
||||
use workspace::item::Item;
|
||||
|
||||
#[gpui::test]
|
||||
|
@ -1574,9 +1574,13 @@ mod tests {
|
|||
// Insert a new file
|
||||
let fs = cx.update_workspace(|workspace, _, cx| workspace.project().read(cx).fs().clone());
|
||||
fs.as_fake()
|
||||
.insert_file("/root/dir/file2.rs", "This is file2.rs".as_bytes().to_vec())
|
||||
.insert_file(
|
||||
path!("/root/dir/file2.rs"),
|
||||
"This is file2.rs".as_bytes().to_vec(),
|
||||
)
|
||||
.await;
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
cx.set_state(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to file2.rs if you want.
|
||||
|
@ -1584,8 +1588,17 @@ mod tests {
|
|||
Or go to /root/dir/file2.rs if project is local.
|
||||
Or go to /root/dir/file2 if this is a Rust file.ˇ
|
||||
"});
|
||||
#[cfg(target_os = "windows")]
|
||||
cx.set_state(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to file2.rs if you want.
|
||||
Or go to ../dir/file2.rs if you want.
|
||||
Or go to C:/root/dir/file2.rs if project is local.
|
||||
Or go to C:/root/dir/file2 if this is a Rust file.ˇ
|
||||
"});
|
||||
|
||||
// File does not exist
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let screen_coord = cx.pixel_position(indoc! {"
|
||||
You can't go to a file that dˇoes_not_exist.txt.
|
||||
Go to file2.rs if you want.
|
||||
|
@ -1593,6 +1606,14 @@ mod tests {
|
|||
Or go to /root/dir/file2.rs if project is local.
|
||||
Or go to /root/dir/file2 if this is a Rust file.
|
||||
"});
|
||||
#[cfg(target_os = "windows")]
|
||||
let screen_coord = cx.pixel_position(indoc! {"
|
||||
You can't go to a file that dˇoes_not_exist.txt.
|
||||
Go to file2.rs if you want.
|
||||
Or go to ../dir/file2.rs if you want.
|
||||
Or go to C:/root/dir/file2.rs if project is local.
|
||||
Or go to C:/root/dir/file2 if this is a Rust file.
|
||||
"});
|
||||
cx.simulate_mouse_move(screen_coord, None, Modifiers::secondary_key());
|
||||
// No highlight
|
||||
cx.update_editor(|editor, window, cx| {
|
||||
|
@ -1605,6 +1626,7 @@ mod tests {
|
|||
});
|
||||
|
||||
// Moving the mouse over a file that does exist should highlight it.
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let screen_coord = cx.pixel_position(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to fˇile2.rs if you want.
|
||||
|
@ -1612,8 +1634,17 @@ mod tests {
|
|||
Or go to /root/dir/file2.rs if project is local.
|
||||
Or go to /root/dir/file2 if this is a Rust file.
|
||||
"});
|
||||
#[cfg(target_os = "windows")]
|
||||
let screen_coord = cx.pixel_position(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to fˇile2.rs if you want.
|
||||
Or go to ../dir/file2.rs if you want.
|
||||
Or go to C:/root/dir/file2.rs if project is local.
|
||||
Or go to C:/root/dir/file2 if this is a Rust file.
|
||||
"});
|
||||
|
||||
cx.simulate_mouse_move(screen_coord, None, Modifiers::secondary_key());
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to «file2.rsˇ» if you want.
|
||||
|
@ -1621,8 +1652,17 @@ mod tests {
|
|||
Or go to /root/dir/file2.rs if project is local.
|
||||
Or go to /root/dir/file2 if this is a Rust file.
|
||||
"});
|
||||
#[cfg(target_os = "windows")]
|
||||
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to «file2.rsˇ» if you want.
|
||||
Or go to ../dir/file2.rs if you want.
|
||||
Or go to C:/root/dir/file2.rs if project is local.
|
||||
Or go to C:/root/dir/file2 if this is a Rust file.
|
||||
"});
|
||||
|
||||
// Moving the mouse over a relative path that does exist should highlight it
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let screen_coord = cx.pixel_position(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to file2.rs if you want.
|
||||
|
@ -1630,8 +1670,17 @@ mod tests {
|
|||
Or go to /root/dir/file2.rs if project is local.
|
||||
Or go to /root/dir/file2 if this is a Rust file.
|
||||
"});
|
||||
#[cfg(target_os = "windows")]
|
||||
let screen_coord = cx.pixel_position(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to file2.rs if you want.
|
||||
Or go to ../dir/fˇile2.rs if you want.
|
||||
Or go to C:/root/dir/file2.rs if project is local.
|
||||
Or go to C:/root/dir/file2 if this is a Rust file.
|
||||
"});
|
||||
|
||||
cx.simulate_mouse_move(screen_coord, None, Modifiers::secondary_key());
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to file2.rs if you want.
|
||||
|
@ -1639,8 +1688,17 @@ mod tests {
|
|||
Or go to /root/dir/file2.rs if project is local.
|
||||
Or go to /root/dir/file2 if this is a Rust file.
|
||||
"});
|
||||
#[cfg(target_os = "windows")]
|
||||
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to file2.rs if you want.
|
||||
Or go to «../dir/file2.rsˇ» if you want.
|
||||
Or go to C:/root/dir/file2.rs if project is local.
|
||||
Or go to C:/root/dir/file2 if this is a Rust file.
|
||||
"});
|
||||
|
||||
// Moving the mouse over an absolute path that does exist should highlight it
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let screen_coord = cx.pixel_position(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to file2.rs if you want.
|
||||
|
@ -1649,7 +1707,17 @@ mod tests {
|
|||
Or go to /root/dir/file2 if this is a Rust file.
|
||||
"});
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let screen_coord = cx.pixel_position(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to file2.rs if you want.
|
||||
Or go to ../dir/file2.rs if you want.
|
||||
Or go to C:/root/diˇr/file2.rs if project is local.
|
||||
Or go to C:/root/dir/file2 if this is a Rust file.
|
||||
"});
|
||||
|
||||
cx.simulate_mouse_move(screen_coord, None, Modifiers::secondary_key());
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to file2.rs if you want.
|
||||
|
@ -1657,8 +1725,17 @@ mod tests {
|
|||
Or go to «/root/dir/file2.rsˇ» if project is local.
|
||||
Or go to /root/dir/file2 if this is a Rust file.
|
||||
"});
|
||||
#[cfg(target_os = "windows")]
|
||||
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to file2.rs if you want.
|
||||
Or go to ../dir/file2.rs if you want.
|
||||
Or go to «C:/root/dir/file2.rsˇ» if project is local.
|
||||
Or go to C:/root/dir/file2 if this is a Rust file.
|
||||
"});
|
||||
|
||||
// Moving the mouse over a path that exists, if we add the language-specific suffix, it should highlight it
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let screen_coord = cx.pixel_position(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to file2.rs if you want.
|
||||
|
@ -1666,8 +1743,17 @@ mod tests {
|
|||
Or go to /root/dir/file2.rs if project is local.
|
||||
Or go to /root/diˇr/file2 if this is a Rust file.
|
||||
"});
|
||||
#[cfg(target_os = "windows")]
|
||||
let screen_coord = cx.pixel_position(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to file2.rs if you want.
|
||||
Or go to ../dir/file2.rs if you want.
|
||||
Or go to C:/root/dir/file2.rs if project is local.
|
||||
Or go to C:/root/diˇr/file2 if this is a Rust file.
|
||||
"});
|
||||
|
||||
cx.simulate_mouse_move(screen_coord, None, Modifiers::secondary_key());
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to file2.rs if you want.
|
||||
|
@ -1675,6 +1761,14 @@ mod tests {
|
|||
Or go to /root/dir/file2.rs if project is local.
|
||||
Or go to «/root/dir/file2ˇ» if this is a Rust file.
|
||||
"});
|
||||
#[cfg(target_os = "windows")]
|
||||
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
||||
You can't go to a file that does_not_exist.txt.
|
||||
Go to file2.rs if you want.
|
||||
Or go to ../dir/file2.rs if you want.
|
||||
Or go to C:/root/dir/file2.rs if project is local.
|
||||
Or go to «C:/root/dir/file2ˇ» if this is a Rust file.
|
||||
"});
|
||||
|
||||
cx.simulate_click(screen_coord, Modifiers::secondary_key());
|
||||
|
||||
|
@ -1692,7 +1786,10 @@ mod tests {
|
|||
let file = buffer.read(cx).file().unwrap();
|
||||
let file_path = file.as_local().unwrap().abs_path(cx);
|
||||
|
||||
assert_eq!(file_path.to_str().unwrap(), "/root/dir/file2.rs");
|
||||
assert_eq!(
|
||||
file_path,
|
||||
std::path::PathBuf::from(path!("/root/dir/file2.rs"))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1274,6 +1274,7 @@ pub mod tests {
|
|||
use settings::SettingsStore;
|
||||
use std::sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering};
|
||||
use text::Point;
|
||||
use util::path;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -1499,7 +1500,7 @@ pub mod tests {
|
|||
|
||||
let fs = FakeFs::new(cx.background_executor.clone());
|
||||
fs.insert_tree(
|
||||
"/a",
|
||||
path!("/a"),
|
||||
json!({
|
||||
"main.rs": "fn main() { a } // and some long comment to ensure inlays are not trimmed out",
|
||||
"other.md": "Test md file with some text",
|
||||
|
@ -1507,7 +1508,7 @@ pub mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/a".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/a").as_ref()], cx).await;
|
||||
|
||||
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
|
||||
let mut rs_fake_servers = None;
|
||||
|
@ -1542,14 +1543,16 @@ pub mod tests {
|
|||
"Rust" => {
|
||||
assert_eq!(
|
||||
params.text_document.uri,
|
||||
lsp::Url::from_file_path("/a/main.rs").unwrap(),
|
||||
lsp::Url::from_file_path(path!("/a/main.rs"))
|
||||
.unwrap(),
|
||||
);
|
||||
rs_lsp_request_count.fetch_add(1, Ordering::Release) + 1
|
||||
}
|
||||
"Markdown" => {
|
||||
assert_eq!(
|
||||
params.text_document.uri,
|
||||
lsp::Url::from_file_path("/a/other.md").unwrap(),
|
||||
lsp::Url::from_file_path(path!("/a/other.md"))
|
||||
.unwrap(),
|
||||
);
|
||||
md_lsp_request_count.fetch_add(1, Ordering::Release) + 1
|
||||
}
|
||||
|
@ -1585,7 +1588,7 @@ pub mod tests {
|
|||
|
||||
let rs_buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/a/main.rs", cx)
|
||||
project.open_local_buffer(path!("/a/main.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -1611,7 +1614,7 @@ pub mod tests {
|
|||
cx.executor().run_until_parked();
|
||||
let md_buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/a/other.md", cx)
|
||||
project.open_local_buffer(path!("/a/other.md"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -2173,7 +2176,7 @@ pub mod tests {
|
|||
|
||||
let fs = FakeFs::new(cx.background_executor.clone());
|
||||
fs.insert_tree(
|
||||
"/a",
|
||||
path!("/a"),
|
||||
json!({
|
||||
"main.rs": format!("fn main() {{\n{}\n}}", "let i = 5;\n".repeat(500)),
|
||||
"other.rs": "// Test file",
|
||||
|
@ -2181,7 +2184,7 @@ pub mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/a".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/a").as_ref()], cx).await;
|
||||
|
||||
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
|
||||
language_registry.add(rust_lang());
|
||||
|
@ -2209,7 +2212,7 @@ pub mod tests {
|
|||
async move {
|
||||
assert_eq!(
|
||||
params.text_document.uri,
|
||||
lsp::Url::from_file_path("/a/main.rs").unwrap(),
|
||||
lsp::Url::from_file_path(path!("/a/main.rs")).unwrap(),
|
||||
);
|
||||
|
||||
task_lsp_request_ranges.lock().push(params.range);
|
||||
|
@ -2237,7 +2240,7 @@ pub mod tests {
|
|||
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/a/main.rs", cx)
|
||||
project.open_local_buffer(path!("/a/main.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -2471,7 +2474,7 @@ pub mod tests {
|
|||
|
||||
let fs = FakeFs::new(cx.background_executor.clone());
|
||||
fs.insert_tree(
|
||||
"/a",
|
||||
path!("/a"),
|
||||
json!({
|
||||
"main.rs": format!("fn main() {{\n{}\n}}", (0..501).map(|i| format!("let i = {i};\n")).collect::<Vec<_>>().join("")),
|
||||
"other.rs": format!("fn main() {{\n{}\n}}", (0..501).map(|j| format!("let j = {j};\n")).collect::<Vec<_>>().join("")),
|
||||
|
@ -2479,7 +2482,7 @@ pub mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/a".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/a").as_ref()], cx).await;
|
||||
|
||||
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
|
||||
let language = rust_lang();
|
||||
|
@ -2497,13 +2500,13 @@ pub mod tests {
|
|||
|
||||
let (buffer_1, _handle1) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp("/a/main.rs", cx)
|
||||
project.open_local_buffer_with_lsp(path!("/a/main.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
let (buffer_2, _handle2) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp("/a/other.rs", cx)
|
||||
project.open_local_buffer_with_lsp(path!("/a/other.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -2585,11 +2588,11 @@ pub mod tests {
|
|||
let task_editor_edited = Arc::clone(&closure_editor_edited);
|
||||
async move {
|
||||
let hint_text = if params.text_document.uri
|
||||
== lsp::Url::from_file_path("/a/main.rs").unwrap()
|
||||
== lsp::Url::from_file_path(path!("/a/main.rs")).unwrap()
|
||||
{
|
||||
"main hint"
|
||||
} else if params.text_document.uri
|
||||
== lsp::Url::from_file_path("/a/other.rs").unwrap()
|
||||
== lsp::Url::from_file_path(path!("/a/other.rs")).unwrap()
|
||||
{
|
||||
"other hint"
|
||||
} else {
|
||||
|
@ -2815,7 +2818,7 @@ pub mod tests {
|
|||
|
||||
let fs = FakeFs::new(cx.background_executor.clone());
|
||||
fs.insert_tree(
|
||||
"/a",
|
||||
path!("/a"),
|
||||
json!({
|
||||
"main.rs": format!("fn main() {{\n{}\n}}", (0..501).map(|i| format!("let i = {i};\n")).collect::<Vec<_>>().join("")),
|
||||
"other.rs": format!("fn main() {{\n{}\n}}", (0..501).map(|j| format!("let j = {j};\n")).collect::<Vec<_>>().join("")),
|
||||
|
@ -2823,7 +2826,7 @@ pub mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/a".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/a").as_ref()], cx).await;
|
||||
|
||||
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
|
||||
language_registry.add(rust_lang());
|
||||
|
@ -2840,13 +2843,13 @@ pub mod tests {
|
|||
|
||||
let (buffer_1, _handle) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp("/a/main.rs", cx)
|
||||
project.open_local_buffer_with_lsp(path!("/a/main.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
let (buffer_2, _handle2) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp("/a/other.rs", cx)
|
||||
project.open_local_buffer_with_lsp(path!("/a/other.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -2886,11 +2889,11 @@ pub mod tests {
|
|||
let task_editor_edited = Arc::clone(&closure_editor_edited);
|
||||
async move {
|
||||
let hint_text = if params.text_document.uri
|
||||
== lsp::Url::from_file_path("/a/main.rs").unwrap()
|
||||
== lsp::Url::from_file_path(path!("/a/main.rs")).unwrap()
|
||||
{
|
||||
"main hint"
|
||||
} else if params.text_document.uri
|
||||
== lsp::Url::from_file_path("/a/other.rs").unwrap()
|
||||
== lsp::Url::from_file_path(path!("/a/other.rs")).unwrap()
|
||||
{
|
||||
"other hint"
|
||||
} else {
|
||||
|
@ -3027,7 +3030,7 @@ pub mod tests {
|
|||
|
||||
let fs = FakeFs::new(cx.background_executor.clone());
|
||||
fs.insert_tree(
|
||||
"/a",
|
||||
path!("/a"),
|
||||
json!({
|
||||
"main.rs": format!(r#"fn main() {{\n{}\n}}"#, format!("let i = {};\n", "√".repeat(10)).repeat(500)),
|
||||
"other.rs": "// Test file",
|
||||
|
@ -3035,7 +3038,7 @@ pub mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/a".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/a").as_ref()], cx).await;
|
||||
|
||||
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
|
||||
language_registry.add(rust_lang());
|
||||
|
@ -3054,7 +3057,7 @@ pub mod tests {
|
|||
async move {
|
||||
assert_eq!(
|
||||
params.text_document.uri,
|
||||
lsp::Url::from_file_path("/a/main.rs").unwrap(),
|
||||
lsp::Url::from_file_path(path!("/a/main.rs")).unwrap(),
|
||||
);
|
||||
let query_start = params.range.start;
|
||||
Ok(Some(vec![lsp::InlayHint {
|
||||
|
@ -3077,7 +3080,7 @@ pub mod tests {
|
|||
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/a/main.rs", cx)
|
||||
project.open_local_buffer(path!("/a/main.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -3250,7 +3253,7 @@ pub mod tests {
|
|||
|
||||
let fs = FakeFs::new(cx.background_executor.clone());
|
||||
fs.insert_tree(
|
||||
"/a",
|
||||
path!("/a"),
|
||||
json!({
|
||||
"main.rs": "fn main() {
|
||||
let x = 42;
|
||||
|
@ -3265,7 +3268,7 @@ pub mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/a".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/a").as_ref()], cx).await;
|
||||
|
||||
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
|
||||
language_registry.add(rust_lang());
|
||||
|
@ -3281,7 +3284,7 @@ pub mod tests {
|
|||
move |params, _| async move {
|
||||
assert_eq!(
|
||||
params.text_document.uri,
|
||||
lsp::Url::from_file_path("/a/main.rs").unwrap(),
|
||||
lsp::Url::from_file_path(path!("/a/main.rs")).unwrap(),
|
||||
);
|
||||
Ok(Some(
|
||||
serde_json::from_value(json!([
|
||||
|
@ -3351,7 +3354,7 @@ pub mod tests {
|
|||
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/a/main.rs", cx)
|
||||
project.open_local_buffer(path!("/a/main.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -3408,7 +3411,7 @@ pub mod tests {
|
|||
) -> (&'static str, WindowHandle<Editor>, FakeLanguageServer) {
|
||||
let fs = FakeFs::new(cx.background_executor.clone());
|
||||
fs.insert_tree(
|
||||
"/a",
|
||||
path!("/a"),
|
||||
json!({
|
||||
"main.rs": "fn main() { a } // and some long comment to ensure inlays are not trimmed out",
|
||||
"other.rs": "// Test file",
|
||||
|
@ -3416,8 +3419,8 @@ pub mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/a".as_ref()], cx).await;
|
||||
let file_path = "/a/main.rs";
|
||||
let project = Project::test(fs, [path!("/a").as_ref()], cx).await;
|
||||
let file_path = path!("/a/main.rs");
|
||||
|
||||
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
|
||||
language_registry.add(rust_lang());
|
||||
|
@ -3435,7 +3438,7 @@ pub mod tests {
|
|||
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/a/main.rs", cx)
|
||||
project.open_local_buffer(path!("/a/main.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
|
@ -1717,6 +1717,7 @@ mod tests {
|
|||
use language::{LanguageMatcher, TestFile};
|
||||
use project::FakeFs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use util::path;
|
||||
|
||||
#[gpui::test]
|
||||
fn test_path_for_file(cx: &mut App) {
|
||||
|
@ -1771,24 +1772,24 @@ mod tests {
|
|||
init_test(cx, |_| {});
|
||||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_file("/file.rs", Default::default()).await;
|
||||
fs.insert_file(path!("/file.rs"), Default::default()).await;
|
||||
|
||||
// Test case 1: Deserialize with path and contents
|
||||
{
|
||||
let project = Project::test(fs.clone(), ["/file.rs".as_ref()], cx).await;
|
||||
let project = Project::test(fs.clone(), [path!("/file.rs").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
let workspace_id = workspace::WORKSPACE_DB.next_id().await.unwrap();
|
||||
let item_id = 1234 as ItemId;
|
||||
let mtime = fs
|
||||
.metadata(Path::new("/file.rs"))
|
||||
.metadata(Path::new(path!("/file.rs")))
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.mtime;
|
||||
|
||||
let serialized_editor = SerializedEditor {
|
||||
abs_path: Some(PathBuf::from("/file.rs")),
|
||||
abs_path: Some(PathBuf::from(path!("/file.rs"))),
|
||||
contents: Some("fn main() {}".to_string()),
|
||||
language: Some("Rust".to_string()),
|
||||
mtime: Some(mtime),
|
||||
|
@ -1812,7 +1813,7 @@ mod tests {
|
|||
|
||||
// Test case 2: Deserialize with only path
|
||||
{
|
||||
let project = Project::test(fs.clone(), ["/file.rs".as_ref()], cx).await;
|
||||
let project = Project::test(fs.clone(), [path!("/file.rs").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
|
||||
|
@ -1820,7 +1821,7 @@ mod tests {
|
|||
|
||||
let item_id = 5678 as ItemId;
|
||||
let serialized_editor = SerializedEditor {
|
||||
abs_path: Some(PathBuf::from("/file.rs")),
|
||||
abs_path: Some(PathBuf::from(path!("/file.rs"))),
|
||||
contents: None,
|
||||
language: None,
|
||||
mtime: None,
|
||||
|
@ -1845,7 +1846,7 @@ mod tests {
|
|||
|
||||
// Test case 3: Deserialize with no path (untitled buffer, with content and language)
|
||||
{
|
||||
let project = Project::test(fs.clone(), ["/file.rs".as_ref()], cx).await;
|
||||
let project = Project::test(fs.clone(), [path!("/file.rs").as_ref()], cx).await;
|
||||
// Add Rust to the language, so that we can restore the language of the buffer
|
||||
project.update(cx, |project, _| project.languages().add(rust_language()));
|
||||
|
||||
|
@ -1884,7 +1885,7 @@ mod tests {
|
|||
|
||||
// Test case 4: Deserialize with path, content, and old mtime
|
||||
{
|
||||
let project = Project::test(fs.clone(), ["/file.rs".as_ref()], cx).await;
|
||||
let project = Project::test(fs.clone(), [path!("/file.rs").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
|
||||
|
@ -1893,7 +1894,7 @@ mod tests {
|
|||
let item_id = 9345 as ItemId;
|
||||
let old_mtime = MTime::from_seconds_and_nanos(0, 50);
|
||||
let serialized_editor = SerializedEditor {
|
||||
abs_path: Some(PathBuf::from("/file.rs")),
|
||||
abs_path: Some(PathBuf::from(path!("/file.rs"))),
|
||||
contents: Some("fn main() {}".to_string()),
|
||||
language: Some("Rust".to_string()),
|
||||
mtime: Some(old_mtime),
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
pub mod editor_lsp_test_context;
|
||||
pub mod editor_test_context;
|
||||
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use crate::{
|
||||
display_map::{DisplayMap, DisplaySnapshot, ToDisplayPoint},
|
||||
DisplayPoint, Editor, EditorMode, FoldPlaceholder, MultiBuffer,
|
||||
};
|
||||
use gpui::{
|
||||
AppContext as _, Context, Entity, Font, FontFeatures, FontStyle, FontWeight, Pixels, Window,
|
||||
font, AppContext as _, Context, Entity, Font, FontFeatures, FontStyle, FontWeight, Pixels,
|
||||
Window,
|
||||
};
|
||||
use project::Project;
|
||||
use util::test::{marked_text_offsets, marked_text_ranges};
|
||||
|
@ -19,6 +22,22 @@ fn init_logger() {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn test_font() -> Font {
|
||||
static TEST_FONT: LazyLock<Font> = LazyLock::new(|| {
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
font("Helvetica")
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
font("Courier New")
|
||||
}
|
||||
});
|
||||
|
||||
TEST_FONT.clone()
|
||||
}
|
||||
|
||||
// Returns a snapshot from text containing '|' character markers with the markers removed, and DisplayPoints for each one.
|
||||
pub fn marked_display_snapshot(
|
||||
text: &str,
|
||||
|
|
|
@ -455,7 +455,12 @@ async fn test_extension_store(cx: &mut TestAppContext) {
|
|||
});
|
||||
}
|
||||
|
||||
// todo(windows)
|
||||
// Disable this test on Windows for now. Because this test hangs at
|
||||
// `let fake_server = fake_servers.next().await.unwrap();`.
|
||||
// Reenable this test when we figure out why.
|
||||
#[gpui::test]
|
||||
#[cfg_attr(target_os = "windows", ignore)]
|
||||
async fn test_extension_store_with_test_extension(cx: &mut TestAppContext) {
|
||||
init_test(cx);
|
||||
cx.executor().allow_parking();
|
||||
|
@ -634,6 +639,8 @@ async fn test_extension_store_with_test_extension(cx: &mut TestAppContext) {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
// todo(windows)
|
||||
// This test hangs here on Windows.
|
||||
let fake_server = fake_servers.next().await.unwrap();
|
||||
let expected_server_path =
|
||||
extensions_dir.join(format!("work/{test_extension_id}/gleam-v1.2.3/gleam"));
|
||||
|
|
|
@ -6,6 +6,7 @@ use gpui::{Entity, TestAppContext, VisualTestContext};
|
|||
use menu::{Confirm, SelectNext, SelectPrev};
|
||||
use project::{RemoveOptions, FS_WATCH_LATENCY};
|
||||
use serde_json::json;
|
||||
use util::path;
|
||||
use workspace::{AppState, ToggleFileFinder, Workspace};
|
||||
|
||||
#[ctor::ctor]
|
||||
|
@ -90,7 +91,7 @@ async fn test_absolute_paths(cx: &mut TestAppContext) {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
"a": {
|
||||
"file1.txt": "",
|
||||
|
@ -102,16 +103,16 @@ async fn test_absolute_paths(cx: &mut TestAppContext) {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
|
||||
let (picker, workspace, cx) = build_find_picker(project, cx);
|
||||
|
||||
let matching_abs_path = "/root/a/b/file2.txt";
|
||||
let matching_abs_path = path!("/root/a/b/file2.txt").to_string();
|
||||
picker
|
||||
.update_in(cx, |picker, window, cx| {
|
||||
picker
|
||||
.delegate
|
||||
.update_matches(matching_abs_path.to_string(), window, cx)
|
||||
.update_matches(matching_abs_path, window, cx)
|
||||
})
|
||||
.await;
|
||||
picker.update(cx, |picker, _| {
|
||||
|
@ -128,12 +129,12 @@ async fn test_absolute_paths(cx: &mut TestAppContext) {
|
|||
assert_eq!(active_editor.read(cx).title(cx), "file2.txt");
|
||||
});
|
||||
|
||||
let mismatching_abs_path = "/root/a/b/file1.txt";
|
||||
let mismatching_abs_path = path!("/root/a/b/file1.txt").to_string();
|
||||
picker
|
||||
.update_in(cx, |picker, window, cx| {
|
||||
picker
|
||||
.delegate
|
||||
.update_matches(mismatching_abs_path.to_string(), window, cx)
|
||||
.update_matches(mismatching_abs_path, window, cx)
|
||||
})
|
||||
.await;
|
||||
picker.update(cx, |picker, _| {
|
||||
|
@ -518,7 +519,7 @@ async fn test_path_distance_ordering(cx: &mut TestAppContext) {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
"dir1": { "a.txt": "" },
|
||||
"dir2": {
|
||||
|
@ -529,7 +530,7 @@ async fn test_path_distance_ordering(cx: &mut TestAppContext) {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
|
||||
let worktree_id = cx.read(|cx| {
|
||||
|
@ -606,7 +607,7 @@ async fn test_query_history(cx: &mut gpui::TestAppContext) {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/src",
|
||||
path!("/src"),
|
||||
json!({
|
||||
"test": {
|
||||
"first.rs": "// First Rust file",
|
||||
|
@ -617,7 +618,7 @@ async fn test_query_history(cx: &mut gpui::TestAppContext) {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/src").as_ref()], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
let worktree_id = cx.read(|cx| {
|
||||
let worktrees = workspace.read(cx).worktrees(cx).collect::<Vec<_>>();
|
||||
|
@ -648,7 +649,7 @@ async fn test_query_history(cx: &mut gpui::TestAppContext) {
|
|||
worktree_id,
|
||||
path: Arc::from(Path::new("test/first.rs")),
|
||||
},
|
||||
Some(PathBuf::from("/src/test/first.rs"))
|
||||
Some(PathBuf::from(path!("/src/test/first.rs")))
|
||||
)],
|
||||
"Should show 1st opened item in the history when opening the 2nd item"
|
||||
);
|
||||
|
@ -663,14 +664,14 @@ async fn test_query_history(cx: &mut gpui::TestAppContext) {
|
|||
worktree_id,
|
||||
path: Arc::from(Path::new("test/second.rs")),
|
||||
},
|
||||
Some(PathBuf::from("/src/test/second.rs"))
|
||||
Some(PathBuf::from(path!("/src/test/second.rs")))
|
||||
),
|
||||
FoundPath::new(
|
||||
ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(Path::new("test/first.rs")),
|
||||
},
|
||||
Some(PathBuf::from("/src/test/first.rs"))
|
||||
Some(PathBuf::from(path!("/src/test/first.rs")))
|
||||
),
|
||||
],
|
||||
"Should show 1st and 2nd opened items in the history when opening the 3rd item. \
|
||||
|
@ -687,21 +688,21 @@ async fn test_query_history(cx: &mut gpui::TestAppContext) {
|
|||
worktree_id,
|
||||
path: Arc::from(Path::new("test/third.rs")),
|
||||
},
|
||||
Some(PathBuf::from("/src/test/third.rs"))
|
||||
Some(PathBuf::from(path!("/src/test/third.rs")))
|
||||
),
|
||||
FoundPath::new(
|
||||
ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(Path::new("test/second.rs")),
|
||||
},
|
||||
Some(PathBuf::from("/src/test/second.rs"))
|
||||
Some(PathBuf::from(path!("/src/test/second.rs")))
|
||||
),
|
||||
FoundPath::new(
|
||||
ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(Path::new("test/first.rs")),
|
||||
},
|
||||
Some(PathBuf::from("/src/test/first.rs"))
|
||||
Some(PathBuf::from(path!("/src/test/first.rs")))
|
||||
),
|
||||
],
|
||||
"Should show 1st, 2nd and 3rd opened items in the history when opening the 2nd item again. \
|
||||
|
@ -718,21 +719,21 @@ async fn test_query_history(cx: &mut gpui::TestAppContext) {
|
|||
worktree_id,
|
||||
path: Arc::from(Path::new("test/second.rs")),
|
||||
},
|
||||
Some(PathBuf::from("/src/test/second.rs"))
|
||||
Some(PathBuf::from(path!("/src/test/second.rs")))
|
||||
),
|
||||
FoundPath::new(
|
||||
ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(Path::new("test/third.rs")),
|
||||
},
|
||||
Some(PathBuf::from("/src/test/third.rs"))
|
||||
Some(PathBuf::from(path!("/src/test/third.rs")))
|
||||
),
|
||||
FoundPath::new(
|
||||
ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(Path::new("test/first.rs")),
|
||||
},
|
||||
Some(PathBuf::from("/src/test/first.rs"))
|
||||
Some(PathBuf::from(path!("/src/test/first.rs")))
|
||||
),
|
||||
],
|
||||
"Should show 1st, 2nd and 3rd opened items in the history when opening the 3rd item again. \
|
||||
|
@ -748,7 +749,7 @@ async fn test_external_files_history(cx: &mut gpui::TestAppContext) {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/src",
|
||||
path!("/src"),
|
||||
json!({
|
||||
"test": {
|
||||
"first.rs": "// First Rust file",
|
||||
|
@ -762,7 +763,7 @@ async fn test_external_files_history(cx: &mut gpui::TestAppContext) {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/external-src",
|
||||
path!("/external-src"),
|
||||
json!({
|
||||
"test": {
|
||||
"third.rs": "// Third Rust file",
|
||||
|
@ -772,10 +773,10 @@ async fn test_external_files_history(cx: &mut gpui::TestAppContext) {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/src").as_ref()], cx).await;
|
||||
cx.update(|cx| {
|
||||
project.update(cx, |project, cx| {
|
||||
project.find_or_create_worktree("/external-src", false, cx)
|
||||
project.find_or_create_worktree(path!("/external-src"), false, cx)
|
||||
})
|
||||
})
|
||||
.detach();
|
||||
|
@ -791,7 +792,7 @@ async fn test_external_files_history(cx: &mut gpui::TestAppContext) {
|
|||
workspace
|
||||
.update_in(cx, |workspace, window, cx| {
|
||||
workspace.open_abs_path(
|
||||
PathBuf::from("/external-src/test/third.rs"),
|
||||
PathBuf::from(path!("/external-src/test/third.rs")),
|
||||
false,
|
||||
window,
|
||||
cx,
|
||||
|
@ -827,7 +828,7 @@ async fn test_external_files_history(cx: &mut gpui::TestAppContext) {
|
|||
worktree_id: external_worktree_id,
|
||||
path: Arc::from(Path::new("")),
|
||||
},
|
||||
Some(PathBuf::from("/external-src/test/third.rs"))
|
||||
Some(PathBuf::from(path!("/external-src/test/third.rs")))
|
||||
)],
|
||||
"Should show external file with its full path in the history after it was open"
|
||||
);
|
||||
|
@ -842,14 +843,14 @@ async fn test_external_files_history(cx: &mut gpui::TestAppContext) {
|
|||
worktree_id,
|
||||
path: Arc::from(Path::new("test/second.rs")),
|
||||
},
|
||||
Some(PathBuf::from("/src/test/second.rs"))
|
||||
Some(PathBuf::from(path!("/src/test/second.rs")))
|
||||
),
|
||||
FoundPath::new(
|
||||
ProjectPath {
|
||||
worktree_id: external_worktree_id,
|
||||
path: Arc::from(Path::new("")),
|
||||
},
|
||||
Some(PathBuf::from("/external-src/test/third.rs"))
|
||||
Some(PathBuf::from(path!("/external-src/test/third.rs")))
|
||||
),
|
||||
],
|
||||
"Should keep external file with history updates",
|
||||
|
@ -864,7 +865,7 @@ async fn test_toggle_panel_new_selections(cx: &mut gpui::TestAppContext) {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/src",
|
||||
path!("/src"),
|
||||
json!({
|
||||
"test": {
|
||||
"first.rs": "// First Rust file",
|
||||
|
@ -875,7 +876,7 @@ async fn test_toggle_panel_new_selections(cx: &mut gpui::TestAppContext) {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/src").as_ref()], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
|
||||
// generate some history to select from
|
||||
|
@ -919,7 +920,7 @@ async fn test_search_preserves_history_items(cx: &mut gpui::TestAppContext) {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/src",
|
||||
path!("/src"),
|
||||
json!({
|
||||
"test": {
|
||||
"first.rs": "// First Rust file",
|
||||
|
@ -931,7 +932,7 @@ async fn test_search_preserves_history_items(cx: &mut gpui::TestAppContext) {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/src").as_ref()], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
let worktree_id = cx.read(|cx| {
|
||||
let worktrees = workspace.read(cx).worktrees(cx).collect::<Vec<_>>();
|
||||
|
@ -964,7 +965,7 @@ async fn test_search_preserves_history_items(cx: &mut gpui::TestAppContext) {
|
|||
worktree_id,
|
||||
path: Arc::from(Path::new("test/first.rs")),
|
||||
},
|
||||
Some(PathBuf::from("/src/test/first.rs"))
|
||||
Some(PathBuf::from(path!("/src/test/first.rs")))
|
||||
));
|
||||
assert_eq!(matches.search.len(), 1, "Only one non-history item contains {first_query}, it should be present");
|
||||
assert_eq!(matches.search.first().unwrap(), Path::new("test/fourth.rs"));
|
||||
|
@ -1007,7 +1008,7 @@ async fn test_search_preserves_history_items(cx: &mut gpui::TestAppContext) {
|
|||
worktree_id,
|
||||
path: Arc::from(Path::new("test/first.rs")),
|
||||
},
|
||||
Some(PathBuf::from("/src/test/first.rs"))
|
||||
Some(PathBuf::from(path!("/src/test/first.rs")))
|
||||
));
|
||||
assert_eq!(matches.search.len(), 1, "Only one non-history item contains {first_query_again}, it should be present, even after non-matching query");
|
||||
assert_eq!(matches.search.first().unwrap(), Path::new("test/fourth.rs"));
|
||||
|
@ -1022,7 +1023,7 @@ async fn test_search_sorts_history_items(cx: &mut gpui::TestAppContext) {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
"test": {
|
||||
"1_qw": "// First file that matches the query",
|
||||
|
@ -1037,7 +1038,7 @@ async fn test_search_sorts_history_items(cx: &mut gpui::TestAppContext) {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
// generate some history to select from
|
||||
open_close_queried_buffer("1", 1, "1_qw", &workspace, cx).await;
|
||||
|
@ -1079,7 +1080,7 @@ async fn test_select_current_open_file_when_no_history(cx: &mut gpui::TestAppCon
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
"test": {
|
||||
"1_qw": "",
|
||||
|
@ -1088,7 +1089,7 @@ async fn test_select_current_open_file_when_no_history(cx: &mut gpui::TestAppCon
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
// Open new buffer
|
||||
open_queried_buffer("1", 1, "1_qw", &workspace, cx).await;
|
||||
|
@ -1109,7 +1110,7 @@ async fn test_keep_opened_file_on_top_of_search_results_and_select_next_one(
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/src",
|
||||
path!("/src"),
|
||||
json!({
|
||||
"test": {
|
||||
"bar.rs": "// Bar file",
|
||||
|
@ -1122,7 +1123,7 @@ async fn test_keep_opened_file_on_top_of_search_results_and_select_next_one(
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/src").as_ref()], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
|
||||
open_close_queried_buffer("bar", 1, "bar.rs", &workspace, cx).await;
|
||||
|
@ -1202,7 +1203,7 @@ async fn test_non_separate_history_items(cx: &mut TestAppContext) {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/src",
|
||||
path!("/src"),
|
||||
json!({
|
||||
"test": {
|
||||
"bar.rs": "// Bar file",
|
||||
|
@ -1215,7 +1216,7 @@ async fn test_non_separate_history_items(cx: &mut TestAppContext) {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/src").as_ref()], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
|
||||
open_close_queried_buffer("bar", 1, "bar.rs", &workspace, cx).await;
|
||||
|
@ -1296,7 +1297,7 @@ async fn test_history_items_shown_in_order_of_open(cx: &mut TestAppContext) {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/test",
|
||||
path!("/test"),
|
||||
json!({
|
||||
"test": {
|
||||
"1.txt": "// One",
|
||||
|
@ -1307,7 +1308,7 @@ async fn test_history_items_shown_in_order_of_open(cx: &mut TestAppContext) {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/test".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/test").as_ref()], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
|
||||
open_queried_buffer("1", 1, "1.txt", &workspace, cx).await;
|
||||
|
@ -1354,7 +1355,7 @@ async fn test_selected_history_item_stays_selected_on_worktree_updated(cx: &mut
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/test",
|
||||
path!("/test"),
|
||||
json!({
|
||||
"test": {
|
||||
"1.txt": "// One",
|
||||
|
@ -1365,7 +1366,7 @@ async fn test_selected_history_item_stays_selected_on_worktree_updated(cx: &mut
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/test".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/test").as_ref()], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
|
||||
open_close_queried_buffer("1", 1, "1.txt", &workspace, cx).await;
|
||||
|
@ -1384,7 +1385,11 @@ async fn test_selected_history_item_stays_selected_on_worktree_updated(cx: &mut
|
|||
|
||||
// Add more files to the worktree to trigger update matches
|
||||
for i in 0..5 {
|
||||
let filename = format!("/test/{}.txt", 4 + i);
|
||||
let filename = if cfg!(windows) {
|
||||
format!("C:/test/{}.txt", 4 + i)
|
||||
} else {
|
||||
format!("/test/{}.txt", 4 + i)
|
||||
};
|
||||
app_state
|
||||
.fs
|
||||
.create_file(Path::new(&filename), Default::default())
|
||||
|
@ -1410,7 +1415,7 @@ async fn test_history_items_vs_very_good_external_match(cx: &mut gpui::TestAppCo
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/src",
|
||||
path!("/src"),
|
||||
json!({
|
||||
"collab_ui": {
|
||||
"first.rs": "// First Rust file",
|
||||
|
@ -1422,7 +1427,7 @@ async fn test_history_items_vs_very_good_external_match(cx: &mut gpui::TestAppCo
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/src").as_ref()], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
// generate some history to select from
|
||||
open_close_queried_buffer("fir", 1, "first.rs", &workspace, cx).await;
|
||||
|
@ -1456,7 +1461,7 @@ async fn test_nonexistent_history_items_not_shown(cx: &mut gpui::TestAppContext)
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/src",
|
||||
path!("/src"),
|
||||
json!({
|
||||
"test": {
|
||||
"first.rs": "// First Rust file",
|
||||
|
@ -1467,7 +1472,7 @@ async fn test_nonexistent_history_items_not_shown(cx: &mut gpui::TestAppContext)
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/src").as_ref()], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx)); // generate some history to select from
|
||||
open_close_queried_buffer("fir", 1, "first.rs", &workspace, cx).await;
|
||||
open_close_queried_buffer("non", 1, "nonexistent.rs", &workspace, cx).await;
|
||||
|
@ -1476,7 +1481,7 @@ async fn test_nonexistent_history_items_not_shown(cx: &mut gpui::TestAppContext)
|
|||
app_state
|
||||
.fs
|
||||
.remove_file(
|
||||
Path::new("/src/test/nonexistent.rs"),
|
||||
Path::new(path!("/src/test/nonexistent.rs")),
|
||||
RemoveOptions::default(),
|
||||
)
|
||||
.await
|
||||
|
@ -1742,14 +1747,14 @@ async fn test_keeps_file_finder_open_after_modifier_keys_release(cx: &mut gpui::
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/test",
|
||||
path!("/test"),
|
||||
json!({
|
||||
"1.txt": "// One",
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/test".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/test").as_ref()], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
|
||||
open_queried_buffer("1", 1, "1.txt", &workspace, cx).await;
|
||||
|
@ -1809,7 +1814,7 @@ async fn test_switches_between_release_norelease_modes_on_forward_nav(
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/test",
|
||||
path!("/test"),
|
||||
json!({
|
||||
"1.txt": "// One",
|
||||
"2.txt": "// Two",
|
||||
|
@ -1817,7 +1822,7 @@ async fn test_switches_between_release_norelease_modes_on_forward_nav(
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/test".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/test").as_ref()], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
|
||||
open_queried_buffer("1", 1, "1.txt", &workspace, cx).await;
|
||||
|
@ -1864,7 +1869,7 @@ async fn test_switches_between_release_norelease_modes_on_backward_nav(
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/test",
|
||||
path!("/test"),
|
||||
json!({
|
||||
"1.txt": "// One",
|
||||
"2.txt": "// Two",
|
||||
|
@ -1873,7 +1878,7 @@ async fn test_switches_between_release_norelease_modes_on_backward_nav(
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/test".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/test").as_ref()], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
|
||||
open_queried_buffer("1", 1, "1.txt", &workspace, cx).await;
|
||||
|
@ -1921,14 +1926,14 @@ async fn test_extending_modifiers_does_not_confirm_selection(cx: &mut gpui::Test
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/test",
|
||||
path!("/test"),
|
||||
json!({
|
||||
"1.txt": "// One",
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/test".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/test").as_ref()], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
|
||||
open_queried_buffer("1", 1, "1.txt", &workspace, cx).await;
|
||||
|
|
|
@ -9,6 +9,8 @@ const BASE_DISTANCE_PENALTY: f64 = 0.6;
|
|||
const ADDITIONAL_DISTANCE_PENALTY: f64 = 0.05;
|
||||
const MIN_DISTANCE_PENALTY: f64 = 0.2;
|
||||
|
||||
// TODO:
|
||||
// Use `Path` instead of `&str` for paths.
|
||||
pub struct Matcher<'a> {
|
||||
query: &'a [char],
|
||||
lowercase_query: &'a [char],
|
||||
|
@ -173,6 +175,8 @@ impl<'a> Matcher<'a> {
|
|||
path_idx: usize,
|
||||
cur_score: f64,
|
||||
) -> f64 {
|
||||
use std::path::MAIN_SEPARATOR;
|
||||
|
||||
if query_idx == self.query.len() {
|
||||
return 1.0;
|
||||
}
|
||||
|
@ -196,13 +200,19 @@ impl<'a> Matcher<'a> {
|
|||
} else {
|
||||
path_cased[j - prefix.len()]
|
||||
};
|
||||
let is_path_sep = path_char == '/' || path_char == '\\';
|
||||
let is_path_sep = path_char == MAIN_SEPARATOR;
|
||||
|
||||
if query_idx == 0 && is_path_sep {
|
||||
last_slash = j;
|
||||
}
|
||||
|
||||
if query_char == path_char || (is_path_sep && query_char == '_' || query_char == '\\') {
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let need_to_score =
|
||||
query_char == path_char || (is_path_sep && query_char == '_' || query_char == '\\');
|
||||
// `query_char == '\\'` breaks `test_match_path_entries` on Windows, `\` is only used as a path separator on Windows.
|
||||
#[cfg(target_os = "windows")]
|
||||
let need_to_score = query_char == path_char || (is_path_sep && query_char == '_');
|
||||
if need_to_score {
|
||||
let curr = if j < prefix.len() {
|
||||
prefix[j]
|
||||
} else {
|
||||
|
@ -217,7 +227,7 @@ impl<'a> Matcher<'a> {
|
|||
path[j - 1 - prefix.len()]
|
||||
};
|
||||
|
||||
if last == '/' {
|
||||
if last == MAIN_SEPARATOR {
|
||||
char_score = 0.9;
|
||||
} else if (last == '-' || last == '_' || last == ' ' || last.is_numeric())
|
||||
|| (last.is_lowercase() && curr.is_uppercase())
|
||||
|
@ -238,7 +248,7 @@ impl<'a> Matcher<'a> {
|
|||
// Apply a severe penalty if the case doesn't match.
|
||||
// This will make the exact matches have higher score than the case-insensitive and the
|
||||
// path insensitive matches.
|
||||
if (self.smart_case || curr == '/') && self.query[query_idx] != curr {
|
||||
if (self.smart_case || curr == MAIN_SEPARATOR) && self.query[query_idx] != curr {
|
||||
char_score *= 0.001;
|
||||
}
|
||||
|
||||
|
@ -322,6 +332,7 @@ mod tests {
|
|||
assert_eq!(matcher.last_positions, vec![0, 3, 4, 8]);
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[test]
|
||||
fn test_match_path_entries() {
|
||||
let paths = vec![
|
||||
|
@ -363,6 +374,54 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
/// todo(windows)
|
||||
/// Now, on Windows, users can only use the backslash as a path separator.
|
||||
/// I do want to support both the backslash and the forward slash as path separators on Windows.
|
||||
#[cfg(target_os = "windows")]
|
||||
#[test]
|
||||
fn test_match_path_entries() {
|
||||
let paths = vec![
|
||||
"",
|
||||
"a",
|
||||
"ab",
|
||||
"abC",
|
||||
"abcd",
|
||||
"alphabravocharlie",
|
||||
"AlphaBravoCharlie",
|
||||
"thisisatestdir",
|
||||
"\\\\\\\\\\ThisIsATestDir",
|
||||
"\\this\\is\\a\\test\\dir",
|
||||
"\\test\\tiatd",
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
match_single_path_query("abc", false, &paths),
|
||||
vec![
|
||||
("abC", vec![0, 1, 2]),
|
||||
("abcd", vec![0, 1, 2]),
|
||||
("AlphaBravoCharlie", vec![0, 5, 10]),
|
||||
("alphabravocharlie", vec![4, 5, 10]),
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
match_single_path_query("t\\i\\a\\t\\d", false, &paths),
|
||||
vec![(
|
||||
"\\this\\is\\a\\test\\dir",
|
||||
vec![1, 5, 6, 8, 9, 10, 11, 15, 16]
|
||||
),]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
match_single_path_query("tiatd", false, &paths),
|
||||
vec![
|
||||
("\\test\\tiatd", vec![6, 7, 8, 9, 10]),
|
||||
("\\this\\is\\a\\test\\dir", vec![1, 6, 9, 11, 16]),
|
||||
("\\\\\\\\\\ThisIsATestDir", vec![5, 9, 11, 12, 16]),
|
||||
("thisisatestdir", vec![0, 2, 6, 7, 11]),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lowercase_longer_than_uppercase() {
|
||||
// This character has more chars in lower-case than in upper-case.
|
||||
|
|
|
@ -353,7 +353,7 @@ mod tests {
|
|||
let want_json =
|
||||
std::fs::read_to_string(&path).unwrap_or_else(|_| {
|
||||
panic!("could not read golden test data file at {:?}. Did you run the test with UPDATE_GOLDEN=true before?", path);
|
||||
});
|
||||
}).replace("\r\n", "\n");
|
||||
|
||||
pretty_assertions::assert_eq!(have_json, want_json, "wrong blame entries");
|
||||
}
|
||||
|
|
|
@ -428,6 +428,12 @@ impl DirectWriteState {
|
|||
target_font.fallbacks.as_ref(),
|
||||
)
|
||||
.unwrap_or_else(|| {
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
{
|
||||
panic!("ERROR: {} font not found!", target_font.family);
|
||||
}
|
||||
#[cfg(not(any(test, feature = "test-support")))]
|
||||
{
|
||||
let family = self.system_ui_font_name.clone();
|
||||
log::error!("{} not found, use {} instead.", target_font.family, family);
|
||||
self.get_font_id_from_font_collection(
|
||||
|
@ -439,6 +445,7 @@ impl DirectWriteState {
|
|||
true,
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -756,21 +756,20 @@ fn should_auto_hide_scrollbars() -> Result<bool> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{ClipboardItem, Platform, WindowsPlatform};
|
||||
use crate::{read_from_clipboard, write_to_clipboard, ClipboardItem};
|
||||
|
||||
#[test]
|
||||
fn test_clipboard() {
|
||||
let platform = WindowsPlatform::new();
|
||||
let item = ClipboardItem::new_string("你好".to_string());
|
||||
platform.write_to_clipboard(item.clone());
|
||||
assert_eq!(platform.read_from_clipboard(), Some(item));
|
||||
let item = ClipboardItem::new_string("你好,我是张小白".to_string());
|
||||
write_to_clipboard(item.clone());
|
||||
assert_eq!(read_from_clipboard(), Some(item));
|
||||
|
||||
let item = ClipboardItem::new_string("12345".to_string());
|
||||
platform.write_to_clipboard(item.clone());
|
||||
assert_eq!(platform.read_from_clipboard(), Some(item));
|
||||
write_to_clipboard(item.clone());
|
||||
assert_eq!(read_from_clipboard(), Some(item));
|
||||
|
||||
let item = ClipboardItem::new_string_with_json_metadata("abcdef".to_string(), vec![3, 4]);
|
||||
platform.write_to_clipboard(item.clone());
|
||||
assert_eq!(platform.read_from_clipboard(), Some(item));
|
||||
write_to_clipboard(item.clone());
|
||||
assert_eq!(read_from_clipboard(), Some(item));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,9 +14,9 @@ proc-macro = true
|
|||
doctest = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0.66"
|
||||
quote = "1.0.9"
|
||||
syn = { version = "1.0.72", features = ["full", "extra-traits"] }
|
||||
proc-macro2.workspace = true
|
||||
quote.workspace = true
|
||||
syn.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
gpui.workspace = true
|
||||
|
|
|
@ -11,6 +11,7 @@ use lsp_log::LogKind;
|
|||
use project::{FakeFs, Project};
|
||||
use serde_json::json;
|
||||
use settings::SettingsStore;
|
||||
use util::path;
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_lsp_logs(cx: &mut TestAppContext) {
|
||||
|
@ -22,7 +23,7 @@ async fn test_lsp_logs(cx: &mut TestAppContext) {
|
|||
|
||||
let fs = FakeFs::new(cx.background_executor.clone());
|
||||
fs.insert_tree(
|
||||
"/the-root",
|
||||
path!("/the-root"),
|
||||
json!({
|
||||
"test.rs": "",
|
||||
"package.json": "",
|
||||
|
@ -30,7 +31,7 @@ async fn test_lsp_logs(cx: &mut TestAppContext) {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs.clone(), ["/the-root".as_ref()], cx).await;
|
||||
let project = Project::test(fs.clone(), [path!("/the-root").as_ref()], cx).await;
|
||||
|
||||
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
|
||||
language_registry.add(Arc::new(Language::new(
|
||||
|
@ -57,7 +58,7 @@ async fn test_lsp_logs(cx: &mut TestAppContext) {
|
|||
|
||||
let _rust_buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp("/the-root/test.rs", cx)
|
||||
project.open_local_buffer_with_lsp(path!("/the-root/test.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
|
@ -818,11 +818,12 @@ mod tests {
|
|||
use lsp::CompletionItemLabelDetails;
|
||||
use settings::SettingsStore;
|
||||
use theme::SyntaxTheme;
|
||||
use util::path;
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_process_rust_diagnostics() {
|
||||
let mut params = lsp::PublishDiagnosticsParams {
|
||||
uri: lsp::Url::from_file_path("/a").unwrap(),
|
||||
uri: lsp::Url::from_file_path(path!("/a")).unwrap(),
|
||||
version: None,
|
||||
diagnostics: vec![
|
||||
// no newlines
|
||||
|
|
|
@ -946,7 +946,7 @@ mod tests {
|
|||
.await {
|
||||
Ok(path) => panic!("Expected to fail for prettier in package.json but not in node_modules found, but got path {path:?}"),
|
||||
Err(e) => {
|
||||
let message = e.to_string();
|
||||
let message = e.to_string().replace("\\\\", "/");
|
||||
assert!(message.contains("/root/work/full-stack-foundations/exercises/03.loading/01.problem.loader"), "Error message should mention which project had prettier defined");
|
||||
assert!(message.contains("/root/work/full-stack-foundations"), "Error message should mention potential candidates without prettier node_modules contents");
|
||||
},
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -18,7 +18,7 @@ use task::{
|
|||
ResolvedTask, TaskContext, TaskId, TaskTemplate, TaskTemplates, TaskVariables, VariableName,
|
||||
};
|
||||
use text::{Point, ToPoint};
|
||||
use util::{post_inc, NumericPrefixWithSuffix, ResultExt as _};
|
||||
use util::{paths::PathExt as _, post_inc, NumericPrefixWithSuffix, ResultExt as _};
|
||||
use worktree::WorktreeId;
|
||||
|
||||
use crate::worktree_store::WorktreeStore;
|
||||
|
@ -470,7 +470,7 @@ impl ContextProvider for BasicContextProvider {
|
|||
let current_file = buffer
|
||||
.file()
|
||||
.and_then(|file| file.as_local())
|
||||
.map(|file| file.abs_path(cx).to_string_lossy().to_string());
|
||||
.map(|file| file.abs_path(cx).to_sanitized_string());
|
||||
let Point { row, column } = location.range.start.to_point(&buffer_snapshot);
|
||||
let row = row + 1;
|
||||
let column = column + 1;
|
||||
|
@ -502,14 +502,14 @@ impl ContextProvider for BasicContextProvider {
|
|||
if let Some(Some(worktree_path)) = worktree_root_dir {
|
||||
task_variables.insert(
|
||||
VariableName::WorktreeRoot,
|
||||
worktree_path.to_string_lossy().to_string(),
|
||||
worktree_path.to_sanitized_string(),
|
||||
);
|
||||
if let Some(full_path) = current_file.as_ref() {
|
||||
let relative_path = pathdiff::diff_paths(full_path, worktree_path);
|
||||
if let Some(relative_path) = relative_path {
|
||||
task_variables.insert(
|
||||
VariableName::RelativeFile,
|
||||
relative_path.to_string_lossy().into_owned(),
|
||||
relative_path.to_sanitized_string(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1106,8 +1106,13 @@ impl ProjectPanel {
|
|||
let worktree_id = edit_state.worktree_id;
|
||||
let is_new_entry = edit_state.is_new_entry();
|
||||
let filename = self.filename_editor.read(cx).text(cx);
|
||||
edit_state.is_dir = edit_state.is_dir
|
||||
|| (edit_state.is_new_entry() && filename.ends_with(std::path::MAIN_SEPARATOR));
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let filename_indicates_dir = filename.ends_with("/");
|
||||
// On Windows, path separator could be either `/` or `\`.
|
||||
#[cfg(target_os = "windows")]
|
||||
let filename_indicates_dir = filename.ends_with("/") || filename.ends_with("\\");
|
||||
edit_state.is_dir =
|
||||
edit_state.is_dir || (edit_state.is_new_entry() && filename_indicates_dir);
|
||||
let is_dir = edit_state.is_dir;
|
||||
let worktree = self.project.read(cx).worktree_for_id(worktree_id, cx)?;
|
||||
let entry = worktree.read(cx).entry_for_id(edit_state.entry_id)?.clone();
|
||||
|
@ -4793,6 +4798,7 @@ mod tests {
|
|||
use serde_json::json;
|
||||
use settings::SettingsStore;
|
||||
use std::path::{Path, PathBuf};
|
||||
use util::{path, separator};
|
||||
use workspace::{
|
||||
item::{Item, ProjectItem},
|
||||
register_project_item, AppState,
|
||||
|
@ -4894,7 +4900,7 @@ mod tests {
|
|||
|
||||
let fs = FakeFs::new(cx.executor().clone());
|
||||
fs.insert_tree(
|
||||
"/src",
|
||||
path!("/src"),
|
||||
json!({
|
||||
"test": {
|
||||
"first.rs": "// First Rust file",
|
||||
|
@ -4905,7 +4911,7 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs.clone(), ["/src".as_ref()], cx).await;
|
||||
let project = Project::test(fs.clone(), [path!("/src").as_ref()], cx).await;
|
||||
let workspace =
|
||||
cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
let cx = &mut VisualTestContext::from_window(*workspace, cx);
|
||||
|
@ -5066,7 +5072,7 @@ mod tests {
|
|||
|
||||
let fs = FakeFs::new(cx.executor().clone());
|
||||
fs.insert_tree(
|
||||
"/root1",
|
||||
path!("/root1"),
|
||||
json!({
|
||||
"dir_1": {
|
||||
"nested_dir_1": {
|
||||
|
@ -5088,7 +5094,7 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
fs.insert_tree(
|
||||
"/root2",
|
||||
path!("/root2"),
|
||||
json!({
|
||||
"dir_2": {
|
||||
"file_1.java": "// File contents",
|
||||
|
@ -5097,7 +5103,12 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await;
|
||||
let project = Project::test(
|
||||
fs.clone(),
|
||||
[path!("/root1").as_ref(), path!("/root2").as_ref()],
|
||||
cx,
|
||||
)
|
||||
.await;
|
||||
let workspace =
|
||||
cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
let cx = &mut VisualTestContext::from_window(*workspace, cx);
|
||||
|
@ -5115,10 +5126,10 @@ mod tests {
|
|||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..10, cx),
|
||||
&[
|
||||
"v root1",
|
||||
" > dir_1/nested_dir_1/nested_dir_2/nested_dir_3",
|
||||
"v root2",
|
||||
" > dir_2",
|
||||
separator!("v root1"),
|
||||
separator!(" > dir_1/nested_dir_1/nested_dir_2/nested_dir_3"),
|
||||
separator!("v root2"),
|
||||
separator!(" > dir_2"),
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -5130,14 +5141,14 @@ mod tests {
|
|||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..10, cx),
|
||||
&[
|
||||
"v root1",
|
||||
" v dir_1/nested_dir_1/nested_dir_2/nested_dir_3 <== selected",
|
||||
" > nested_dir_4/nested_dir_5",
|
||||
" file_a.java",
|
||||
" file_b.java",
|
||||
" file_c.java",
|
||||
"v root2",
|
||||
" > dir_2",
|
||||
separator!("v root1"),
|
||||
separator!(" v dir_1/nested_dir_1/nested_dir_2/nested_dir_3 <== selected"),
|
||||
separator!(" > nested_dir_4/nested_dir_5"),
|
||||
separator!(" file_a.java"),
|
||||
separator!(" file_b.java"),
|
||||
separator!(" file_c.java"),
|
||||
separator!("v root2"),
|
||||
separator!(" > dir_2"),
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -5149,31 +5160,31 @@ mod tests {
|
|||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..10, cx),
|
||||
&[
|
||||
"v root1",
|
||||
" v dir_1/nested_dir_1/nested_dir_2/nested_dir_3",
|
||||
" v nested_dir_4/nested_dir_5 <== selected",
|
||||
" file_d.java",
|
||||
" file_a.java",
|
||||
" file_b.java",
|
||||
" file_c.java",
|
||||
"v root2",
|
||||
" > dir_2",
|
||||
separator!("v root1"),
|
||||
separator!(" v dir_1/nested_dir_1/nested_dir_2/nested_dir_3"),
|
||||
separator!(" v nested_dir_4/nested_dir_5 <== selected"),
|
||||
separator!(" file_d.java"),
|
||||
separator!(" file_a.java"),
|
||||
separator!(" file_b.java"),
|
||||
separator!(" file_c.java"),
|
||||
separator!("v root2"),
|
||||
separator!(" > dir_2"),
|
||||
]
|
||||
);
|
||||
toggle_expand_dir(&panel, "root2/dir_2", cx);
|
||||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..10, cx),
|
||||
&[
|
||||
"v root1",
|
||||
" v dir_1/nested_dir_1/nested_dir_2/nested_dir_3",
|
||||
" v nested_dir_4/nested_dir_5",
|
||||
" file_d.java",
|
||||
" file_a.java",
|
||||
" file_b.java",
|
||||
" file_c.java",
|
||||
"v root2",
|
||||
" v dir_2 <== selected",
|
||||
" file_1.java",
|
||||
separator!("v root1"),
|
||||
separator!(" v dir_1/nested_dir_1/nested_dir_2/nested_dir_3"),
|
||||
separator!(" v nested_dir_4/nested_dir_5"),
|
||||
separator!(" file_d.java"),
|
||||
separator!(" file_a.java"),
|
||||
separator!(" file_b.java"),
|
||||
separator!(" file_c.java"),
|
||||
separator!("v root2"),
|
||||
separator!(" v dir_2 <== selected"),
|
||||
separator!(" file_1.java"),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -5682,7 +5693,7 @@ mod tests {
|
|||
|
||||
let fs = FakeFs::new(cx.executor().clone());
|
||||
fs.insert_tree(
|
||||
"/root1",
|
||||
path!("/root1"),
|
||||
json!({
|
||||
".dockerignore": "",
|
||||
".git": {
|
||||
|
@ -5692,7 +5703,7 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs.clone(), ["/root1".as_ref()], cx).await;
|
||||
let project = Project::test(fs.clone(), [path!("/root1").as_ref()], cx).await;
|
||||
let workspace =
|
||||
cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
let cx = &mut VisualTestContext::from_window(*workspace, cx);
|
||||
|
@ -5727,9 +5738,10 @@ mod tests {
|
|||
);
|
||||
|
||||
let confirm = panel.update_in(cx, |panel, window, cx| {
|
||||
// If we want to create a subdirectory, there should be no prefix slash.
|
||||
panel
|
||||
.filename_editor
|
||||
.update(cx, |editor, cx| editor.set_text("/new_dir/", window, cx));
|
||||
.update(cx, |editor, cx| editor.set_text("new_dir/", window, cx));
|
||||
panel.confirm_edit(window, cx).unwrap()
|
||||
});
|
||||
|
||||
|
@ -5738,14 +5750,14 @@ mod tests {
|
|||
&[
|
||||
"v root1",
|
||||
" > .git",
|
||||
" [PROCESSING: '/new_dir/'] <== selected",
|
||||
" [PROCESSING: 'new_dir/'] <== selected",
|
||||
" .dockerignore",
|
||||
]
|
||||
);
|
||||
|
||||
confirm.await.unwrap();
|
||||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..13, cx),
|
||||
visible_entries_as_strings(&panel, 0..10, cx),
|
||||
&[
|
||||
"v root1",
|
||||
" > .git",
|
||||
|
@ -5753,6 +5765,54 @@ mod tests {
|
|||
" .dockerignore",
|
||||
]
|
||||
);
|
||||
|
||||
// Test filename with whitespace
|
||||
select_path(&panel, "root1", cx);
|
||||
panel.update_in(cx, |panel, window, cx| panel.new_file(&NewFile, window, cx));
|
||||
let confirm = panel.update_in(cx, |panel, window, cx| {
|
||||
// If we want to create a subdirectory, there should be no prefix slash.
|
||||
panel
|
||||
.filename_editor
|
||||
.update(cx, |editor, cx| editor.set_text("new dir 2/", window, cx));
|
||||
panel.confirm_edit(window, cx).unwrap()
|
||||
});
|
||||
confirm.await.unwrap();
|
||||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..10, cx),
|
||||
&[
|
||||
"v root1",
|
||||
" > .git",
|
||||
" v new dir 2 <== selected",
|
||||
" v new_dir",
|
||||
" .dockerignore",
|
||||
]
|
||||
);
|
||||
|
||||
// Test filename ends with "\"
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
select_path(&panel, "root1", cx);
|
||||
panel.update_in(cx, |panel, window, cx| panel.new_file(&NewFile, window, cx));
|
||||
let confirm = panel.update_in(cx, |panel, window, cx| {
|
||||
// If we want to create a subdirectory, there should be no prefix slash.
|
||||
panel
|
||||
.filename_editor
|
||||
.update(cx, |editor, cx| editor.set_text("new_dir_3\\", window, cx));
|
||||
panel.confirm_edit(window, cx).unwrap()
|
||||
});
|
||||
confirm.await.unwrap();
|
||||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..10, cx),
|
||||
&[
|
||||
"v root1",
|
||||
" > .git",
|
||||
" v new dir 2",
|
||||
" v new_dir",
|
||||
" v new_dir_3 <== selected",
|
||||
" .dockerignore",
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
|
@ -6409,7 +6469,7 @@ mod tests {
|
|||
|
||||
let fs = FakeFs::new(cx.executor().clone());
|
||||
fs.insert_tree(
|
||||
"/src",
|
||||
path!("/src"),
|
||||
json!({
|
||||
"test": {
|
||||
"first.rs": "// First Rust file",
|
||||
|
@ -6420,7 +6480,7 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs.clone(), ["/src".as_ref()], cx).await;
|
||||
let project = Project::test(fs.clone(), [path!("/src").as_ref()], cx).await;
|
||||
let workspace =
|
||||
cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
let cx = &mut VisualTestContext::from_window(*workspace, cx);
|
||||
|
@ -8545,7 +8605,7 @@ mod tests {
|
|||
|
||||
let fs = FakeFs::new(cx.executor().clone());
|
||||
fs.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
".gitignore": "**/ignored_dir\n**/ignored_nested",
|
||||
"dir1": {
|
||||
|
@ -8573,7 +8633,7 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
let workspace =
|
||||
cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
let cx = &mut VisualTestContext::from_window(*workspace, cx);
|
||||
|
@ -8602,12 +8662,12 @@ mod tests {
|
|||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..20, cx),
|
||||
&[
|
||||
"v root",
|
||||
" v dir1 <== selected",
|
||||
" > empty1/empty2/empty3",
|
||||
" > ignored_dir",
|
||||
" > subdir1",
|
||||
" .gitignore",
|
||||
separator!("v root"),
|
||||
separator!(" v dir1 <== selected"),
|
||||
separator!(" > empty1/empty2/empty3"),
|
||||
separator!(" > ignored_dir"),
|
||||
separator!(" > subdir1"),
|
||||
separator!(" .gitignore"),
|
||||
],
|
||||
"Should show first level with auto-folded dirs and ignored dir visible"
|
||||
);
|
||||
|
@ -8624,18 +8684,18 @@ mod tests {
|
|||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..20, cx),
|
||||
&[
|
||||
"v root",
|
||||
" v dir1 <== selected",
|
||||
" v empty1",
|
||||
" v empty2",
|
||||
" v empty3",
|
||||
" file.txt",
|
||||
" > ignored_dir",
|
||||
" v subdir1",
|
||||
" > ignored_nested",
|
||||
" file1.txt",
|
||||
" file2.txt",
|
||||
" .gitignore",
|
||||
separator!("v root"),
|
||||
separator!(" v dir1 <== selected"),
|
||||
separator!(" v empty1"),
|
||||
separator!(" v empty2"),
|
||||
separator!(" v empty3"),
|
||||
separator!(" file.txt"),
|
||||
separator!(" > ignored_dir"),
|
||||
separator!(" v subdir1"),
|
||||
separator!(" > ignored_nested"),
|
||||
separator!(" file1.txt"),
|
||||
separator!(" file2.txt"),
|
||||
separator!(" .gitignore"),
|
||||
],
|
||||
"After expand_all with auto-fold: should not expand ignored_dir, should expand folded dirs, and should not expand ignored_nested"
|
||||
);
|
||||
|
@ -8660,12 +8720,12 @@ mod tests {
|
|||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..20, cx),
|
||||
&[
|
||||
"v root",
|
||||
" v dir1 <== selected",
|
||||
" > empty1",
|
||||
" > ignored_dir",
|
||||
" > subdir1",
|
||||
" .gitignore",
|
||||
separator!("v root"),
|
||||
separator!(" v dir1 <== selected"),
|
||||
separator!(" > empty1"),
|
||||
separator!(" > ignored_dir"),
|
||||
separator!(" > subdir1"),
|
||||
separator!(" .gitignore"),
|
||||
],
|
||||
"With auto-fold disabled: should show all directories separately"
|
||||
);
|
||||
|
@ -8682,18 +8742,18 @@ mod tests {
|
|||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..20, cx),
|
||||
&[
|
||||
"v root",
|
||||
" v dir1 <== selected",
|
||||
" v empty1",
|
||||
" v empty2",
|
||||
" v empty3",
|
||||
" file.txt",
|
||||
" > ignored_dir",
|
||||
" v subdir1",
|
||||
" > ignored_nested",
|
||||
" file1.txt",
|
||||
" file2.txt",
|
||||
" .gitignore",
|
||||
separator!("v root"),
|
||||
separator!(" v dir1 <== selected"),
|
||||
separator!(" v empty1"),
|
||||
separator!(" v empty2"),
|
||||
separator!(" v empty3"),
|
||||
separator!(" file.txt"),
|
||||
separator!(" > ignored_dir"),
|
||||
separator!(" v subdir1"),
|
||||
separator!(" > ignored_nested"),
|
||||
separator!(" file1.txt"),
|
||||
separator!(" file2.txt"),
|
||||
separator!(" .gitignore"),
|
||||
],
|
||||
"After expand_all without auto-fold: should expand all dirs normally, \
|
||||
expand ignored_dir itself but not its subdirs, and not expand ignored_nested"
|
||||
|
@ -8712,20 +8772,20 @@ mod tests {
|
|||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..20, cx),
|
||||
&[
|
||||
"v root",
|
||||
" v dir1 <== selected",
|
||||
" v empty1",
|
||||
" v empty2",
|
||||
" v empty3",
|
||||
" file.txt",
|
||||
" v ignored_dir",
|
||||
" v subdir",
|
||||
" deep_file.txt",
|
||||
" v subdir1",
|
||||
" > ignored_nested",
|
||||
" file1.txt",
|
||||
" file2.txt",
|
||||
" .gitignore",
|
||||
separator!("v root"),
|
||||
separator!(" v dir1 <== selected"),
|
||||
separator!(" v empty1"),
|
||||
separator!(" v empty2"),
|
||||
separator!(" v empty3"),
|
||||
separator!(" file.txt"),
|
||||
separator!(" v ignored_dir"),
|
||||
separator!(" v subdir"),
|
||||
separator!(" deep_file.txt"),
|
||||
separator!(" v subdir1"),
|
||||
separator!(" > ignored_nested"),
|
||||
separator!(" file1.txt"),
|
||||
separator!(" file2.txt"),
|
||||
separator!(" .gitignore"),
|
||||
],
|
||||
"After expand_all on ignored_dir: should expand all contents of the ignored directory"
|
||||
);
|
||||
|
@ -8737,7 +8797,7 @@ mod tests {
|
|||
|
||||
let fs = FakeFs::new(cx.executor().clone());
|
||||
fs.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
"dir1": {
|
||||
"subdir1": {
|
||||
|
@ -8759,7 +8819,7 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
let workspace =
|
||||
cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
let cx = &mut VisualTestContext::from_window(*workspace, cx);
|
||||
|
@ -8776,15 +8836,15 @@ mod tests {
|
|||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..20, cx),
|
||||
&[
|
||||
"v root",
|
||||
" v dir1",
|
||||
" v subdir1",
|
||||
" v nested1",
|
||||
" file1.txt",
|
||||
" file2.txt",
|
||||
" v subdir2 <== selected",
|
||||
" file4.txt",
|
||||
" > dir2",
|
||||
separator!("v root"),
|
||||
separator!(" v dir1"),
|
||||
separator!(" v subdir1"),
|
||||
separator!(" v nested1"),
|
||||
separator!(" file1.txt"),
|
||||
separator!(" file2.txt"),
|
||||
separator!(" v subdir2 <== selected"),
|
||||
separator!(" file4.txt"),
|
||||
separator!(" > dir2"),
|
||||
],
|
||||
"Initial state with everything expanded"
|
||||
);
|
||||
|
@ -8826,13 +8886,13 @@ mod tests {
|
|||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..20, cx),
|
||||
&[
|
||||
"v root",
|
||||
" v dir1",
|
||||
" v subdir1/nested1 <== selected",
|
||||
" file1.txt",
|
||||
" file2.txt",
|
||||
" > subdir2",
|
||||
" > dir2/single_file",
|
||||
separator!("v root"),
|
||||
separator!(" v dir1"),
|
||||
separator!(" v subdir1/nested1 <== selected"),
|
||||
separator!(" file1.txt"),
|
||||
separator!(" file2.txt"),
|
||||
separator!(" > subdir2"),
|
||||
separator!(" > dir2/single_file"),
|
||||
],
|
||||
"Initial state with some dirs expanded"
|
||||
);
|
||||
|
@ -8849,11 +8909,11 @@ mod tests {
|
|||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..20, cx),
|
||||
&[
|
||||
"v root",
|
||||
" v dir1 <== selected",
|
||||
" > subdir1/nested1",
|
||||
" > subdir2",
|
||||
" > dir2/single_file",
|
||||
separator!("v root"),
|
||||
separator!(" v dir1 <== selected"),
|
||||
separator!(" > subdir1/nested1"),
|
||||
separator!(" > subdir2"),
|
||||
separator!(" > dir2/single_file"),
|
||||
],
|
||||
"Subdirs should be collapsed and folded with auto-fold enabled"
|
||||
);
|
||||
|
@ -8881,14 +8941,14 @@ mod tests {
|
|||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..20, cx),
|
||||
&[
|
||||
"v root",
|
||||
" v dir1",
|
||||
" v subdir1",
|
||||
" v nested1 <== selected",
|
||||
" file1.txt",
|
||||
" file2.txt",
|
||||
" > subdir2",
|
||||
" > dir2",
|
||||
separator!("v root"),
|
||||
separator!(" v dir1"),
|
||||
separator!(" v subdir1"),
|
||||
separator!(" v nested1 <== selected"),
|
||||
separator!(" file1.txt"),
|
||||
separator!(" file2.txt"),
|
||||
separator!(" > subdir2"),
|
||||
separator!(" > dir2"),
|
||||
],
|
||||
"Initial state with some dirs expanded and auto-fold disabled"
|
||||
);
|
||||
|
@ -8905,11 +8965,11 @@ mod tests {
|
|||
assert_eq!(
|
||||
visible_entries_as_strings(&panel, 0..20, cx),
|
||||
&[
|
||||
"v root",
|
||||
" v dir1 <== selected",
|
||||
" > subdir1",
|
||||
" > subdir2",
|
||||
" > dir2",
|
||||
separator!("v root"),
|
||||
separator!(" v dir1 <== selected"),
|
||||
separator!(" > subdir1"),
|
||||
separator!(" > subdir2"),
|
||||
separator!(" > dir2"),
|
||||
],
|
||||
"Subdirs should be collapsed but not folded with auto-fold disabled"
|
||||
);
|
||||
|
|
|
@ -272,15 +272,17 @@ mod tests {
|
|||
use serde_json::json;
|
||||
use settings::SettingsStore;
|
||||
use std::{path::Path, sync::Arc};
|
||||
use util::path;
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_project_symbols(cx: &mut TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree("/dir", json!({ "test.rs": "" })).await;
|
||||
fs.insert_tree(path!("/dir"), json!({ "test.rs": "" }))
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await;
|
||||
let project = Project::test(fs.clone(), [path!("/dir").as_ref()], cx).await;
|
||||
|
||||
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
|
||||
language_registry.add(Arc::new(Language::new(
|
||||
|
@ -299,7 +301,7 @@ mod tests {
|
|||
|
||||
let _buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp("/dir/test.rs", cx)
|
||||
project.open_local_buffer_with_lsp(path!("/dir/test.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -307,9 +309,9 @@ mod tests {
|
|||
// Set up fake language server to return fuzzy matches against
|
||||
// a fixed set of symbol names.
|
||||
let fake_symbols = [
|
||||
symbol("one", "/external"),
|
||||
symbol("ton", "/dir/test.rs"),
|
||||
symbol("uno", "/dir/test.rs"),
|
||||
symbol("one", path!("/external")),
|
||||
symbol("ton", path!("/dir/test.rs")),
|
||||
symbol("uno", path!("/dir/test.rs")),
|
||||
];
|
||||
let fake_server = fake_servers.next().await.unwrap();
|
||||
fake_server.handle_request::<lsp::WorkspaceSymbolRequest, _, _>(
|
||||
|
|
|
@ -595,6 +595,7 @@ mod tests {
|
|||
use project::{project_settings::ProjectSettings, Project};
|
||||
use serde_json::json;
|
||||
use settings::SettingsStore;
|
||||
use util::path;
|
||||
use workspace::{open_paths, AppState};
|
||||
|
||||
use super::*;
|
||||
|
@ -615,7 +616,7 @@ mod tests {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/dir",
|
||||
path!("/dir"),
|
||||
json!({
|
||||
"main.ts": "a"
|
||||
}),
|
||||
|
@ -623,7 +624,7 @@ mod tests {
|
|||
.await;
|
||||
cx.update(|cx| {
|
||||
open_paths(
|
||||
&[PathBuf::from("/dir/main.ts")],
|
||||
&[PathBuf::from(path!("/dir/main.ts"))],
|
||||
app_state,
|
||||
workspace::OpenOptions::default(),
|
||||
cx,
|
||||
|
|
|
@ -14,6 +14,6 @@ proc-macro = true
|
|||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
syn = "1.0.72"
|
||||
quote = "1.0.9"
|
||||
proc-macro2 = "1.0.66"
|
||||
proc-macro2.workspace = true
|
||||
quote.workspace = true
|
||||
syn.workspace = true
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
/// todo(windows)
|
||||
/// The tests in this file assume that server_cx is running on Windows too.
|
||||
/// We neead to find a way to test Windows-Non-Windows interactions.
|
||||
use crate::headless_project::HeadlessProject;
|
||||
use client::{Client, UserStore};
|
||||
use clock::FakeSystemClock;
|
||||
|
@ -24,12 +27,13 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use util::{path, separator};
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_basic_remote_editing(cx: &mut TestAppContext, server_cx: &mut TestAppContext) {
|
||||
let fs = FakeFs::new(server_cx.executor());
|
||||
fs.insert_tree(
|
||||
"/code",
|
||||
path!("/code"),
|
||||
json!({
|
||||
"project1": {
|
||||
".git": {},
|
||||
|
@ -45,14 +49,14 @@ async fn test_basic_remote_editing(cx: &mut TestAppContext, server_cx: &mut Test
|
|||
)
|
||||
.await;
|
||||
fs.set_index_for_repo(
|
||||
Path::new("/code/project1/.git"),
|
||||
Path::new(path!("/code/project1/.git")),
|
||||
&[("src/lib.rs".into(), "fn one() -> usize { 0 }".into())],
|
||||
);
|
||||
|
||||
let (project, _headless) = init_test(&fs, cx, server_cx).await;
|
||||
let (worktree, _) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.find_or_create_worktree("/code/project1", true, cx)
|
||||
project.find_or_create_worktree(path!("/code/project1"), true, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -113,7 +117,7 @@ async fn test_basic_remote_editing(cx: &mut TestAppContext, server_cx: &mut Test
|
|||
// A new file is created in the remote filesystem. The user
|
||||
// sees the new file.
|
||||
fs.save(
|
||||
"/code/project1/src/main.rs".as_ref(),
|
||||
path!("/code/project1/src/main.rs").as_ref(),
|
||||
&"fn main() {}".into(),
|
||||
Default::default(),
|
||||
)
|
||||
|
@ -134,8 +138,8 @@ async fn test_basic_remote_editing(cx: &mut TestAppContext, server_cx: &mut Test
|
|||
|
||||
// A file that is currently open in a buffer is renamed.
|
||||
fs.rename(
|
||||
"/code/project1/src/lib.rs".as_ref(),
|
||||
"/code/project1/src/lib2.rs".as_ref(),
|
||||
path!("/code/project1/src/lib.rs").as_ref(),
|
||||
path!("/code/project1/src/lib2.rs").as_ref(),
|
||||
Default::default(),
|
||||
)
|
||||
.await
|
||||
|
@ -146,7 +150,7 @@ async fn test_basic_remote_editing(cx: &mut TestAppContext, server_cx: &mut Test
|
|||
});
|
||||
|
||||
fs.set_index_for_repo(
|
||||
Path::new("/code/project1/.git"),
|
||||
Path::new(path!("/code/project1/.git")),
|
||||
&[("src/lib2.rs".into(), "fn one() -> usize { 100 }".into())],
|
||||
);
|
||||
cx.executor().run_until_parked();
|
||||
|
@ -162,7 +166,7 @@ async fn test_basic_remote_editing(cx: &mut TestAppContext, server_cx: &mut Test
|
|||
async fn test_remote_project_search(cx: &mut TestAppContext, server_cx: &mut TestAppContext) {
|
||||
let fs = FakeFs::new(server_cx.executor());
|
||||
fs.insert_tree(
|
||||
"/code",
|
||||
path!("/code"),
|
||||
json!({
|
||||
"project1": {
|
||||
".git": {},
|
||||
|
@ -179,7 +183,7 @@ async fn test_remote_project_search(cx: &mut TestAppContext, server_cx: &mut Tes
|
|||
|
||||
project
|
||||
.update(cx, |project, cx| {
|
||||
project.find_or_create_worktree("/code/project1", true, cx)
|
||||
project.find_or_create_worktree(path!("/code/project1"), true, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -210,7 +214,7 @@ async fn test_remote_project_search(cx: &mut TestAppContext, server_cx: &mut Tes
|
|||
buffer.update(&mut cx, |buffer, cx| {
|
||||
assert_eq!(
|
||||
buffer.file().unwrap().full_path(cx).to_string_lossy(),
|
||||
"project1/README.md"
|
||||
separator!("project1/README.md")
|
||||
)
|
||||
});
|
||||
|
||||
|
@ -368,7 +372,7 @@ async fn test_remote_settings(cx: &mut TestAppContext, server_cx: &mut TestAppCo
|
|||
async fn test_remote_lsp(cx: &mut TestAppContext, server_cx: &mut TestAppContext) {
|
||||
let fs = FakeFs::new(server_cx.executor());
|
||||
fs.insert_tree(
|
||||
"/code",
|
||||
path!("/code"),
|
||||
json!({
|
||||
"project1": {
|
||||
".git": {},
|
||||
|
@ -384,7 +388,7 @@ async fn test_remote_lsp(cx: &mut TestAppContext, server_cx: &mut TestAppContext
|
|||
let (project, headless) = init_test(&fs, cx, server_cx).await;
|
||||
|
||||
fs.insert_tree(
|
||||
"/code/project1/.zed",
|
||||
path!("/code/project1/.zed"),
|
||||
json!({
|
||||
"settings.json": r#"
|
||||
{
|
||||
|
@ -431,7 +435,7 @@ async fn test_remote_lsp(cx: &mut TestAppContext, server_cx: &mut TestAppContext
|
|||
|
||||
let worktree_id = project
|
||||
.update(cx, |project, cx| {
|
||||
project.find_or_create_worktree("/code/project1", true, cx)
|
||||
project.find_or_create_worktree(path!("/code/project1"), true, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
|
@ -512,7 +516,7 @@ async fn test_remote_lsp(cx: &mut TestAppContext, server_cx: &mut TestAppContext
|
|||
Ok(Some(lsp::WorkspaceEdit {
|
||||
changes: Some(
|
||||
[(
|
||||
lsp::Url::from_file_path("/code/project1/src/lib.rs").unwrap(),
|
||||
lsp::Url::from_file_path(path!("/code/project1/src/lib.rs")).unwrap(),
|
||||
vec![lsp::TextEdit::new(
|
||||
lsp::Range::new(lsp::Position::new(0, 3), lsp::Position::new(0, 6)),
|
||||
"two".to_string(),
|
||||
|
@ -545,7 +549,7 @@ async fn test_remote_cancel_language_server_work(
|
|||
) {
|
||||
let fs = FakeFs::new(server_cx.executor());
|
||||
fs.insert_tree(
|
||||
"/code",
|
||||
path!("/code"),
|
||||
json!({
|
||||
"project1": {
|
||||
".git": {},
|
||||
|
@ -561,7 +565,7 @@ async fn test_remote_cancel_language_server_work(
|
|||
let (project, headless) = init_test(&fs, cx, server_cx).await;
|
||||
|
||||
fs.insert_tree(
|
||||
"/code/project1/.zed",
|
||||
path!("/code/project1/.zed"),
|
||||
json!({
|
||||
"settings.json": r#"
|
||||
{
|
||||
|
@ -608,7 +612,7 @@ async fn test_remote_cancel_language_server_work(
|
|||
|
||||
let worktree_id = project
|
||||
.update(cx, |project, cx| {
|
||||
project.find_or_create_worktree("/code/project1", true, cx)
|
||||
project.find_or_create_worktree(path!("/code/project1"), true, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
|
@ -708,7 +712,7 @@ async fn test_remote_cancel_language_server_work(
|
|||
async fn test_remote_reload(cx: &mut TestAppContext, server_cx: &mut TestAppContext) {
|
||||
let fs = FakeFs::new(server_cx.executor());
|
||||
fs.insert_tree(
|
||||
"/code",
|
||||
path!("/code"),
|
||||
json!({
|
||||
"project1": {
|
||||
".git": {},
|
||||
|
@ -724,7 +728,7 @@ async fn test_remote_reload(cx: &mut TestAppContext, server_cx: &mut TestAppCont
|
|||
let (project, _headless) = init_test(&fs, cx, server_cx).await;
|
||||
let (worktree, _) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.find_or_create_worktree("/code/project1", true, cx)
|
||||
project.find_or_create_worktree(path!("/code/project1"), true, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -739,7 +743,7 @@ async fn test_remote_reload(cx: &mut TestAppContext, server_cx: &mut TestAppCont
|
|||
.unwrap();
|
||||
|
||||
fs.save(
|
||||
&PathBuf::from("/code/project1/src/lib.rs"),
|
||||
&PathBuf::from(path!("/code/project1/src/lib.rs")),
|
||||
&("bangles".to_string().into()),
|
||||
LineEnding::Unix,
|
||||
)
|
||||
|
@ -754,7 +758,7 @@ async fn test_remote_reload(cx: &mut TestAppContext, server_cx: &mut TestAppCont
|
|||
});
|
||||
|
||||
fs.save(
|
||||
&PathBuf::from("/code/project1/src/lib.rs"),
|
||||
&PathBuf::from(path!("/code/project1/src/lib.rs")),
|
||||
&("bloop".to_string().into()),
|
||||
LineEnding::Unix,
|
||||
)
|
||||
|
@ -786,7 +790,7 @@ async fn test_remote_resolve_path_in_buffer(
|
|||
) {
|
||||
let fs = FakeFs::new(server_cx.executor());
|
||||
fs.insert_tree(
|
||||
"/code",
|
||||
path!("/code"),
|
||||
json!({
|
||||
"project1": {
|
||||
".git": {},
|
||||
|
@ -802,7 +806,7 @@ async fn test_remote_resolve_path_in_buffer(
|
|||
let (project, _headless) = init_test(&fs, cx, server_cx).await;
|
||||
let (worktree, _) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.find_or_create_worktree("/code/project1", true, cx)
|
||||
project.find_or_create_worktree(path!("/code/project1"), true, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -818,14 +822,14 @@ async fn test_remote_resolve_path_in_buffer(
|
|||
|
||||
let path = project
|
||||
.update(cx, |project, cx| {
|
||||
project.resolve_path_in_buffer("/code/project1/README.md", &buffer, cx)
|
||||
project.resolve_path_in_buffer(path!("/code/project1/README.md"), &buffer, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(path.is_file());
|
||||
assert_eq!(
|
||||
path.abs_path().unwrap().to_string_lossy(),
|
||||
"/code/project1/README.md"
|
||||
path!("/code/project1/README.md")
|
||||
);
|
||||
|
||||
let path = project
|
||||
|
@ -1013,7 +1017,7 @@ async fn test_adding_then_removing_then_adding_worktrees(
|
|||
async fn test_open_server_settings(cx: &mut TestAppContext, server_cx: &mut TestAppContext) {
|
||||
let fs = FakeFs::new(server_cx.executor());
|
||||
fs.insert_tree(
|
||||
"/code",
|
||||
path!("/code"),
|
||||
json!({
|
||||
"project1": {
|
||||
".git": {},
|
||||
|
@ -1035,7 +1039,9 @@ async fn test_open_server_settings(cx: &mut TestAppContext, server_cx: &mut Test
|
|||
cx.update(|cx| {
|
||||
assert_eq!(
|
||||
buffer.read(cx).text(),
|
||||
initial_server_settings_content().to_string()
|
||||
initial_server_settings_content()
|
||||
.to_string()
|
||||
.replace("\r\n", "\n")
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -1044,7 +1050,7 @@ async fn test_open_server_settings(cx: &mut TestAppContext, server_cx: &mut Test
|
|||
async fn test_reconnect(cx: &mut TestAppContext, server_cx: &mut TestAppContext) {
|
||||
let fs = FakeFs::new(server_cx.executor());
|
||||
fs.insert_tree(
|
||||
"/code",
|
||||
path!("/code"),
|
||||
json!({
|
||||
"project1": {
|
||||
".git": {},
|
||||
|
@ -1061,7 +1067,7 @@ async fn test_reconnect(cx: &mut TestAppContext, server_cx: &mut TestAppContext)
|
|||
|
||||
let (worktree, _) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.find_or_create_worktree("/code/project1", true, cx)
|
||||
project.find_or_create_worktree(path!("/code/project1"), true, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -1091,7 +1097,9 @@ async fn test_reconnect(cx: &mut TestAppContext, server_cx: &mut TestAppContext)
|
|||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
fs.load("/code/project1/src/lib.rs".as_ref()).await.unwrap(),
|
||||
fs.load(path!("/code/project1/src/lib.rs").as_ref())
|
||||
.await
|
||||
.unwrap(),
|
||||
"fn one() -> usize { 100 }"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2188,6 +2188,7 @@ pub mod tests {
|
|||
use project::FakeFs;
|
||||
use serde_json::json;
|
||||
use settings::SettingsStore;
|
||||
use util::path;
|
||||
use workspace::DeploySearch;
|
||||
|
||||
#[gpui::test]
|
||||
|
@ -3313,13 +3314,13 @@ pub mod tests {
|
|||
|
||||
let fs = FakeFs::new(cx.background_executor.clone());
|
||||
fs.insert_tree(
|
||||
"/dir",
|
||||
path!("/dir"),
|
||||
json!({
|
||||
"one.rs": "const ONE: usize = 1;",
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await;
|
||||
let project = Project::test(fs.clone(), [path!("/dir").as_ref()], cx).await;
|
||||
let worktree_id = project.update(cx, |this, cx| {
|
||||
this.worktrees(cx).next().unwrap().read(cx).id()
|
||||
});
|
||||
|
@ -3537,13 +3538,13 @@ pub mod tests {
|
|||
// Setup 2 panes, both with a file open and one with a project search.
|
||||
let fs = FakeFs::new(cx.background_executor.clone());
|
||||
fs.insert_tree(
|
||||
"/dir",
|
||||
path!("/dir"),
|
||||
json!({
|
||||
"one.rs": "const ONE: usize = 1;",
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await;
|
||||
let project = Project::test(fs.clone(), [path!("/dir").as_ref()], cx).await;
|
||||
let worktree_id = project.update(cx, |this, cx| {
|
||||
this.worktrees(cx).next().unwrap().read(cx).id()
|
||||
});
|
||||
|
@ -3771,13 +3772,13 @@ pub mod tests {
|
|||
|
||||
let fs = FakeFs::new(cx.background_executor.clone());
|
||||
fs.insert_tree(
|
||||
"/dir",
|
||||
path!("/dir"),
|
||||
json!({
|
||||
"one.rs": "const ONE: usize = 1;",
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await;
|
||||
let project = Project::test(fs.clone(), [path!("/dir").as_ref()], cx).await;
|
||||
let worktree_id = project.update(cx, |this, cx| {
|
||||
this.worktrees(cx).next().unwrap().read(cx).id()
|
||||
});
|
||||
|
|
|
@ -44,9 +44,9 @@ sha2.workspace = true
|
|||
smol.workspace = true
|
||||
theme.workspace = true
|
||||
tree-sitter.workspace = true
|
||||
ui. workspace = true
|
||||
ui.workspace = true
|
||||
unindent.workspace = true
|
||||
util. workspace = true
|
||||
util.workspace = true
|
||||
workspace.workspace = true
|
||||
worktree.workspace = true
|
||||
|
||||
|
|
|
@ -279,6 +279,7 @@ mod tests {
|
|||
use settings::SettingsStore;
|
||||
use smol::channel;
|
||||
use std::{future, path::Path, sync::Arc};
|
||||
use util::separator;
|
||||
|
||||
fn init_test(cx: &mut TestAppContext) {
|
||||
env_logger::try_init().ok();
|
||||
|
@ -421,7 +422,10 @@ mod tests {
|
|||
// Find result that is greater than 0.5
|
||||
let search_result = results.iter().find(|result| result.score > 0.9).unwrap();
|
||||
|
||||
assert_eq!(search_result.path.to_string_lossy(), "fixture/needle.md");
|
||||
assert_eq!(
|
||||
search_result.path.to_string_lossy(),
|
||||
separator!("fixture/needle.md")
|
||||
);
|
||||
|
||||
let content = cx
|
||||
.update(|cx| {
|
||||
|
|
|
@ -12,6 +12,7 @@ pub fn test_settings() -> String {
|
|||
crate::default_settings().as_ref(),
|
||||
)
|
||||
.unwrap();
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
util::merge_non_null_json_value_into(
|
||||
serde_json::json!({
|
||||
"ui_font_family": "Courier",
|
||||
|
@ -26,6 +27,21 @@ pub fn test_settings() -> String {
|
|||
}),
|
||||
&mut value,
|
||||
);
|
||||
#[cfg(target_os = "windows")]
|
||||
util::merge_non_null_json_value_into(
|
||||
serde_json::json!({
|
||||
"ui_font_family": "Courier New",
|
||||
"ui_font_features": {},
|
||||
"ui_font_size": 14,
|
||||
"ui_font_fallback": [],
|
||||
"buffer_font_family": "Courier New",
|
||||
"buffer_font_features": {},
|
||||
"buffer_font_size": 14,
|
||||
"buffer_font_fallback": [],
|
||||
"theme": EMPTY_THEME_NAME,
|
||||
}),
|
||||
&mut value,
|
||||
);
|
||||
value.as_object_mut().unwrap().remove("languages");
|
||||
serde_json::to_string(&value).unwrap()
|
||||
}
|
||||
|
|
|
@ -16,4 +16,4 @@ doctest = false
|
|||
[dependencies]
|
||||
sqlez.workspace = true
|
||||
sqlformat.workspace = true
|
||||
syn = "1.0"
|
||||
syn.workspace = true
|
||||
|
|
|
@ -5,6 +5,7 @@ use menu::SelectPrev;
|
|||
use project::{Project, ProjectPath};
|
||||
use serde_json::json;
|
||||
use std::path::Path;
|
||||
use util::path;
|
||||
use workspace::{AppState, Workspace};
|
||||
|
||||
#[ctor::ctor]
|
||||
|
@ -24,7 +25,7 @@ async fn test_open_with_prev_tab_selected_and_cycle_on_toggle_action(
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
"1.txt": "First file",
|
||||
"2.txt": "Second file",
|
||||
|
@ -34,7 +35,7 @@ async fn test_open_with_prev_tab_selected_and_cycle_on_toggle_action(
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
|
||||
|
@ -81,7 +82,7 @@ async fn test_open_with_last_tab_selected(cx: &mut gpui::TestAppContext) {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
"1.txt": "First file",
|
||||
"2.txt": "Second file",
|
||||
|
@ -90,7 +91,7 @@ async fn test_open_with_last_tab_selected(cx: &mut gpui::TestAppContext) {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
|
||||
|
@ -172,10 +173,10 @@ async fn test_open_with_single_item(cx: &mut gpui::TestAppContext) {
|
|||
app_state
|
||||
.fs
|
||||
.as_fake()
|
||||
.insert_tree("/root", json!({"1.txt": "Single file"}))
|
||||
.insert_tree(path!("/root"), json!({"1.txt": "Single file"}))
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
|
||||
|
@ -195,7 +196,7 @@ async fn test_close_selected_item(cx: &mut gpui::TestAppContext) {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
"1.txt": "First file",
|
||||
"2.txt": "Second file",
|
||||
|
@ -203,7 +204,7 @@ async fn test_close_selected_item(cx: &mut gpui::TestAppContext) {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
|
||||
|
@ -241,7 +242,7 @@ async fn test_close_preserves_selected_position(cx: &mut gpui::TestAppContext) {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
"1.txt": "First file",
|
||||
"2.txt": "Second file",
|
||||
|
@ -250,7 +251,7 @@ async fn test_close_preserves_selected_position(cx: &mut gpui::TestAppContext) {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
|
||||
|
|
|
@ -603,6 +603,7 @@ mod tests {
|
|||
use project::{ContextProviderWithTasks, FakeFs, Project};
|
||||
use serde_json::json;
|
||||
use task::TaskTemplates;
|
||||
use util::path;
|
||||
use workspace::CloseInactiveTabsAndPanes;
|
||||
|
||||
use crate::{modal::Spawn, tests::init_test};
|
||||
|
@ -614,7 +615,7 @@ mod tests {
|
|||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
"/dir",
|
||||
path!("/dir"),
|
||||
json!({
|
||||
".zed": {
|
||||
"tasks.json": r#"[
|
||||
|
@ -635,7 +636,7 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/dir".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/dir").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
|
||||
|
@ -654,7 +655,7 @@ mod tests {
|
|||
|
||||
let _ = workspace
|
||||
.update_in(cx, |workspace, window, cx| {
|
||||
workspace.open_abs_path(PathBuf::from("/dir/a.ts"), true, window, cx)
|
||||
workspace.open_abs_path(PathBuf::from(path!("/dir/a.ts")), true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -778,7 +779,7 @@ mod tests {
|
|||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
"/dir",
|
||||
path!("/dir"),
|
||||
json!({
|
||||
".zed": {
|
||||
"tasks.json": r#"[
|
||||
|
@ -800,7 +801,7 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/dir".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/dir").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
|
||||
|
@ -819,7 +820,7 @@ mod tests {
|
|||
let _ = workspace
|
||||
.update_in(cx, |workspace, window, cx| {
|
||||
workspace.open_abs_path(
|
||||
PathBuf::from("/dir/file_with.odd_extension"),
|
||||
PathBuf::from(path!("/dir/file_with.odd_extension")),
|
||||
true,
|
||||
window,
|
||||
cx,
|
||||
|
@ -832,8 +833,8 @@ mod tests {
|
|||
assert_eq!(
|
||||
task_names(&tasks_picker, cx),
|
||||
vec![
|
||||
"hello from /dir/file_with.odd_extension:1:1".to_string(),
|
||||
"opened now: /dir".to_string()
|
||||
concat!("hello from ", path!("/dir/file_with.odd_extension:1:1")).to_string(),
|
||||
concat!("opened now: ", path!("/dir")).to_string(),
|
||||
],
|
||||
"Second opened buffer should fill the context, labels should be trimmed if long enough"
|
||||
);
|
||||
|
@ -846,7 +847,7 @@ mod tests {
|
|||
let second_item = workspace
|
||||
.update_in(cx, |workspace, window, cx| {
|
||||
workspace.open_abs_path(
|
||||
PathBuf::from("/dir/file_without_extension"),
|
||||
PathBuf::from(path!("/dir/file_without_extension")),
|
||||
true,
|
||||
window,
|
||||
cx,
|
||||
|
@ -868,8 +869,8 @@ mod tests {
|
|||
assert_eq!(
|
||||
task_names(&tasks_picker, cx),
|
||||
vec![
|
||||
"hello from /dir/file_without_extension:2:3".to_string(),
|
||||
"opened now: /dir".to_string()
|
||||
concat!("hello from ", path!("/dir/file_without_extension:2:3")).to_string(),
|
||||
concat!("opened now: ", path!("/dir")).to_string(),
|
||||
],
|
||||
"Opened buffer should fill the context, labels should be trimmed if long enough"
|
||||
);
|
||||
|
@ -885,7 +886,7 @@ mod tests {
|
|||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
"/dir",
|
||||
path!("/dir"),
|
||||
json!({
|
||||
"a1.ts": "// a1",
|
||||
"a2.ts": "// a2",
|
||||
|
@ -894,7 +895,7 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/dir".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/dir").as_ref()], cx).await;
|
||||
project.read_with(cx, |project, _| {
|
||||
let language_registry = project.languages();
|
||||
language_registry.add(Arc::new(
|
||||
|
@ -955,7 +956,7 @@ mod tests {
|
|||
|
||||
let _ts_file_1 = workspace
|
||||
.update_in(cx, |workspace, window, cx| {
|
||||
workspace.open_abs_path(PathBuf::from("/dir/a1.ts"), true, window, cx)
|
||||
workspace.open_abs_path(PathBuf::from(path!("/dir/a1.ts")), true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -963,23 +964,28 @@ mod tests {
|
|||
assert_eq!(
|
||||
task_names(&tasks_picker, cx),
|
||||
vec![
|
||||
"Another task from file /dir/a1.ts",
|
||||
"TypeScript task from file /dir/a1.ts",
|
||||
concat!("Another task from file ", path!("/dir/a1.ts")),
|
||||
concat!("TypeScript task from file ", path!("/dir/a1.ts")),
|
||||
"Task without variables",
|
||||
],
|
||||
"Should open spawn TypeScript tasks for the opened file, tasks with most template variables above, all groups sorted alphanumerically"
|
||||
);
|
||||
|
||||
emulate_task_schedule(
|
||||
tasks_picker,
|
||||
&project,
|
||||
"TypeScript task from file /dir/a1.ts",
|
||||
concat!("TypeScript task from file ", path!("/dir/a1.ts")),
|
||||
cx,
|
||||
);
|
||||
|
||||
let tasks_picker = open_spawn_tasks(&workspace, cx);
|
||||
assert_eq!(
|
||||
task_names(&tasks_picker, cx),
|
||||
vec!["TypeScript task from file /dir/a1.ts", "Another task from file /dir/a1.ts", "Task without variables"],
|
||||
vec![
|
||||
concat!("TypeScript task from file ", path!("/dir/a1.ts")),
|
||||
concat!("Another task from file ", path!("/dir/a1.ts")),
|
||||
"Task without variables",
|
||||
],
|
||||
"After spawning the task and getting it into the history, it should be up in the sort as recently used.
|
||||
Tasks with the same labels and context are deduplicated."
|
||||
);
|
||||
|
@ -991,7 +997,7 @@ mod tests {
|
|||
|
||||
let _ts_file_2 = workspace
|
||||
.update_in(cx, |workspace, window, cx| {
|
||||
workspace.open_abs_path(PathBuf::from("/dir/a2.ts"), true, window, cx)
|
||||
workspace.open_abs_path(PathBuf::from(path!("/dir/a2.ts")), true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -999,10 +1005,10 @@ mod tests {
|
|||
assert_eq!(
|
||||
task_names(&tasks_picker, cx),
|
||||
vec![
|
||||
"TypeScript task from file /dir/a1.ts",
|
||||
"Another task from file /dir/a2.ts",
|
||||
"TypeScript task from file /dir/a2.ts",
|
||||
"Task without variables"
|
||||
concat!("TypeScript task from file ", path!("/dir/a1.ts")),
|
||||
concat!("Another task from file ", path!("/dir/a2.ts")),
|
||||
concat!("TypeScript task from file ", path!("/dir/a2.ts")),
|
||||
"Task without variables",
|
||||
],
|
||||
"Even when both TS files are open, should only show the history (on the top), and tasks, resolved for the current file"
|
||||
);
|
||||
|
@ -1029,7 +1035,7 @@ mod tests {
|
|||
emulate_task_schedule(tasks_picker, &project, "Rust task", cx);
|
||||
let _ts_file_2 = workspace
|
||||
.update_in(cx, |workspace, window, cx| {
|
||||
workspace.open_abs_path(PathBuf::from("/dir/a2.ts"), true, window, cx)
|
||||
workspace.open_abs_path(PathBuf::from(path!("/dir/a2.ts")), true, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -1037,10 +1043,10 @@ mod tests {
|
|||
assert_eq!(
|
||||
task_names(&tasks_picker, cx),
|
||||
vec![
|
||||
"TypeScript task from file /dir/a1.ts",
|
||||
"Another task from file /dir/a2.ts",
|
||||
"TypeScript task from file /dir/a2.ts",
|
||||
"Task without variables"
|
||||
concat!("TypeScript task from file ", path!("/dir/a1.ts")),
|
||||
concat!("Another task from file ", path!("/dir/a2.ts")),
|
||||
concat!("TypeScript task from file ", path!("/dir/a2.ts")),
|
||||
"Task without variables",
|
||||
],
|
||||
"After closing all but *.rs tabs, running a Rust task and switching back to TS tasks, \
|
||||
same TS spawn history should be restored"
|
||||
|
|
|
@ -262,6 +262,7 @@ mod tests {
|
|||
use serde_json::json;
|
||||
use task::{TaskContext, TaskVariables, VariableName};
|
||||
use ui::VisualContext;
|
||||
use util::{path, separator};
|
||||
use workspace::{AppState, Workspace};
|
||||
|
||||
use crate::task_context;
|
||||
|
@ -271,7 +272,7 @@ mod tests {
|
|||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
"/dir",
|
||||
path!("/dir"),
|
||||
json!({
|
||||
".zed": {
|
||||
"tasks.json": r#"[
|
||||
|
@ -295,7 +296,7 @@ mod tests {
|
|||
}),
|
||||
)
|
||||
.await;
|
||||
let project = Project::test(fs, ["/dir".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/dir").as_ref()], cx).await;
|
||||
let worktree_store = project.update(cx, |project, _| project.worktree_store().clone());
|
||||
let rust_language = Arc::new(
|
||||
Language::new(
|
||||
|
@ -375,17 +376,18 @@ mod tests {
|
|||
task_context(workspace, window, cx)
|
||||
})
|
||||
.await;
|
||||
|
||||
assert_eq!(
|
||||
first_context,
|
||||
TaskContext {
|
||||
cwd: Some("/dir".into()),
|
||||
cwd: Some(path!("/dir").into()),
|
||||
task_variables: TaskVariables::from_iter([
|
||||
(VariableName::File, "/dir/rust/b.rs".into()),
|
||||
(VariableName::File, path!("/dir/rust/b.rs").into()),
|
||||
(VariableName::Filename, "b.rs".into()),
|
||||
(VariableName::RelativeFile, "rust/b.rs".into()),
|
||||
(VariableName::Dirname, "/dir/rust".into()),
|
||||
(VariableName::RelativeFile, separator!("rust/b.rs").into()),
|
||||
(VariableName::Dirname, path!("/dir/rust").into()),
|
||||
(VariableName::Stem, "b".into()),
|
||||
(VariableName::WorktreeRoot, "/dir".into()),
|
||||
(VariableName::WorktreeRoot, path!("/dir").into()),
|
||||
(VariableName::Row, "1".into()),
|
||||
(VariableName::Column, "1".into()),
|
||||
]),
|
||||
|
@ -407,14 +409,14 @@ mod tests {
|
|||
})
|
||||
.await,
|
||||
TaskContext {
|
||||
cwd: Some("/dir".into()),
|
||||
cwd: Some(path!("/dir").into()),
|
||||
task_variables: TaskVariables::from_iter([
|
||||
(VariableName::File, "/dir/rust/b.rs".into()),
|
||||
(VariableName::File, path!("/dir/rust/b.rs").into()),
|
||||
(VariableName::Filename, "b.rs".into()),
|
||||
(VariableName::RelativeFile, "rust/b.rs".into()),
|
||||
(VariableName::Dirname, "/dir/rust".into()),
|
||||
(VariableName::RelativeFile, separator!("rust/b.rs").into()),
|
||||
(VariableName::Dirname, path!("/dir/rust").into()),
|
||||
(VariableName::Stem, "b".into()),
|
||||
(VariableName::WorktreeRoot, "/dir".into()),
|
||||
(VariableName::WorktreeRoot, path!("/dir").into()),
|
||||
(VariableName::Row, "1".into()),
|
||||
(VariableName::Column, "15".into()),
|
||||
(VariableName::SelectedText, "is_i".into()),
|
||||
|
@ -433,14 +435,14 @@ mod tests {
|
|||
})
|
||||
.await,
|
||||
TaskContext {
|
||||
cwd: Some("/dir".into()),
|
||||
cwd: Some(path!("/dir").into()),
|
||||
task_variables: TaskVariables::from_iter([
|
||||
(VariableName::File, "/dir/a.ts".into()),
|
||||
(VariableName::File, path!("/dir/a.ts").into()),
|
||||
(VariableName::Filename, "a.ts".into()),
|
||||
(VariableName::RelativeFile, "a.ts".into()),
|
||||
(VariableName::Dirname, "/dir".into()),
|
||||
(VariableName::Dirname, path!("/dir").into()),
|
||||
(VariableName::Stem, "a".into()),
|
||||
(VariableName::WorktreeRoot, "/dir".into()),
|
||||
(VariableName::WorktreeRoot, path!("/dir").into()),
|
||||
(VariableName::Row, "1".into()),
|
||||
(VariableName::Column, "1".into()),
|
||||
(VariableName::Symbol, "this_is_a_test".into()),
|
||||
|
|
|
@ -13,7 +13,7 @@ path = "src/ui_macros.rs"
|
|||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0.66"
|
||||
quote = "1.0.9"
|
||||
syn = { version = "1.0.72", features = ["full", "extra-traits"] }
|
||||
proc-macro2.workspace = true
|
||||
quote.workspace = true
|
||||
syn.workspace = true
|
||||
convert_case.workspace = true
|
||||
|
|
|
@ -13,7 +13,7 @@ path = "src/util.rs"
|
|||
doctest = true
|
||||
|
||||
[features]
|
||||
test-support = ["tempfile", "git2", "rand"]
|
||||
test-support = ["tempfile", "git2", "rand", "util_macros"]
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
|
@ -35,6 +35,7 @@ smol.workspace = true
|
|||
take-until.workspace = true
|
||||
tempfile = { workspace = true, optional = true }
|
||||
unicase.workspace = true
|
||||
util_macros = { workspace = true, optional = true }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc.workspace = true
|
||||
|
@ -47,3 +48,4 @@ dunce = "1.0"
|
|||
git2.workspace = true
|
||||
rand.workspace = true
|
||||
tempfile.workspace = true
|
||||
util_macros.workspace = true
|
||||
|
|
|
@ -23,6 +23,7 @@ pub trait PathExt {
|
|||
fn compact(&self) -> PathBuf;
|
||||
fn icon_stem_or_suffix(&self) -> Option<&str>;
|
||||
fn extension_or_hidden_file_name(&self) -> Option<&str>;
|
||||
fn to_sanitized_string(&self) -> String;
|
||||
fn try_from_bytes<'a>(bytes: &'a [u8]) -> anyhow::Result<Self>
|
||||
where
|
||||
Self: From<&'a Path>,
|
||||
|
@ -94,6 +95,20 @@ impl<T: AsRef<Path>> PathExt for T {
|
|||
|
||||
self.as_ref().file_name()?.to_str()?.split('.').last()
|
||||
}
|
||||
|
||||
/// Returns a sanitized string representation of the path.
|
||||
/// Note, on Windows, this assumes that the path is a valid UTF-8 string and
|
||||
/// is not a UNC path.
|
||||
fn to_sanitized_string(&self) -> String {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
self.as_ref().to_string_lossy().replace("/", "\\")
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
self.as_ref().to_string_lossy().to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Due to the issue of UNC paths on Windows, which can cause bugs in various parts of Zed, introducing this `SanitizedPath`
|
||||
|
@ -115,6 +130,17 @@ impl SanitizedPath {
|
|||
self.0.to_string_lossy().to_string()
|
||||
}
|
||||
|
||||
pub fn to_glob_string(&self) -> String {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
self.0.to_string_lossy().replace("/", "\\")
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
self.0.to_string_lossy().to_string()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn join(&self, path: &Self) -> Self {
|
||||
self.0.join(&path.0).into()
|
||||
}
|
||||
|
@ -448,14 +474,6 @@ pub fn compare_paths(
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn replace_path_separator(path: &str) -> String {
|
||||
#[cfg(target_os = "windows")]
|
||||
return path.replace("/", std::path::MAIN_SEPARATOR_STR);
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
return path.to_string();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -28,6 +28,8 @@ use unicase::UniCase;
|
|||
use anyhow::{anyhow, Context as _};
|
||||
|
||||
pub use take_until::*;
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub use util_macros::{separator, uri};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! debug_panic {
|
||||
|
@ -41,6 +43,50 @@ macro_rules! debug_panic {
|
|||
};
|
||||
}
|
||||
|
||||
/// A macro to add "C:" to the beginning of a path literal on Windows, and replace all
|
||||
/// the separator from `/` to `\`.
|
||||
/// But on non-Windows platforms, it will return the path literal as is.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// use util::path;
|
||||
///
|
||||
/// let path = path!("/Users/user/file.txt");
|
||||
/// #[cfg(target_os = "windows")]
|
||||
/// assert_eq!(path, "C:\\Users\\user\\file.txt");
|
||||
/// #[cfg(not(target_os = "windows"))]
|
||||
/// assert_eq!(path, "/Users/user/file.txt");
|
||||
/// ```
|
||||
#[cfg(all(any(test, feature = "test-support"), target_os = "windows"))]
|
||||
#[macro_export]
|
||||
macro_rules! path {
|
||||
($path:literal) => {
|
||||
concat!("C:", util::separator!($path))
|
||||
};
|
||||
}
|
||||
|
||||
/// A macro to add "C:" to the beginning of a path literal on Windows, and replace all
|
||||
/// the separator from `/` to `\`.
|
||||
/// But on non-Windows platforms, it will return the path literal as is.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// use util::path;
|
||||
///
|
||||
/// let path = path!("/Users/user/file.txt");
|
||||
/// #[cfg(target_os = "windows")]
|
||||
/// assert_eq!(path, "C:\\Users\\user\\file.txt");
|
||||
/// #[cfg(not(target_os = "windows"))]
|
||||
/// assert_eq!(path, "/Users/user/file.txt");
|
||||
/// ```
|
||||
#[cfg(all(any(test, feature = "test-support"), not(target_os = "windows")))]
|
||||
#[macro_export]
|
||||
macro_rules! path {
|
||||
($path:literal) => {
|
||||
$path
|
||||
};
|
||||
}
|
||||
|
||||
pub fn truncate(s: &str, max_chars: usize) -> &str {
|
||||
match s.char_indices().nth(max_chars) {
|
||||
None => s,
|
||||
|
|
18
crates/util_macros/Cargo.toml
Normal file
18
crates/util_macros/Cargo.toml
Normal file
|
@ -0,0 +1,18 @@
|
|||
[package]
|
||||
name = "util_macros"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
publish.workspace = true
|
||||
license = "GPL-3.0-or-later"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[lib]
|
||||
path = "src/util_macros.rs"
|
||||
proc-macro = true
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
quote.workspace = true
|
||||
syn.workspace = true
|
1
crates/util_macros/LICENSE-APACHE
Symbolic link
1
crates/util_macros/LICENSE-APACHE
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../LICENSE-APACHE
|
56
crates/util_macros/src/util_macros.rs
Normal file
56
crates/util_macros/src/util_macros.rs
Normal file
|
@ -0,0 +1,56 @@
|
|||
#![cfg_attr(not(target_os = "windows"), allow(unused))]
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, LitStr};
|
||||
|
||||
/// This macro replaces the path separator `/` with `\` for Windows.
|
||||
/// But if the target OS is not Windows, the path is returned as is.
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust
|
||||
/// # use util_macros::separator;
|
||||
/// let path = separator!("path/to/file");
|
||||
/// #[cfg(target_os = "windows")]
|
||||
/// assert_eq!(path, "path\\to\\file");
|
||||
/// #[cfg(not(target_os = "windows"))]
|
||||
/// assert_eq!(path, "path/to/file");
|
||||
/// ```
|
||||
#[proc_macro]
|
||||
pub fn separator(input: TokenStream) -> TokenStream {
|
||||
let path = parse_macro_input!(input as LitStr);
|
||||
let path = path.value();
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let path = path.replace("/", "\\");
|
||||
|
||||
TokenStream::from(quote! {
|
||||
#path
|
||||
})
|
||||
}
|
||||
|
||||
/// This macro replaces the path prefix `file:///` with `file:///C:/` for Windows.
|
||||
/// But if the target OS is not Windows, the URI is returned as is.
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust
|
||||
/// use util_macros::uri;
|
||||
///
|
||||
/// let uri = uri!("file:///path/to/file");
|
||||
/// #[cfg(target_os = "windows")]
|
||||
/// assert_eq!(uri, "file:///C:/path/to/file");
|
||||
/// #[cfg(not(target_os = "windows"))]
|
||||
/// assert_eq!(uri, "file:///path/to/file");
|
||||
/// ```
|
||||
#[proc_macro]
|
||||
pub fn uri(input: TokenStream) -> TokenStream {
|
||||
let uri = parse_macro_input!(input as LitStr);
|
||||
let uri = uri.value();
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let uri = uri.replace("file:///", "file:///C:/");
|
||||
|
||||
TokenStream::from(quote! {
|
||||
#uri
|
||||
})
|
||||
}
|
|
@ -1455,6 +1455,7 @@ mod test {
|
|||
use editor::Editor;
|
||||
use gpui::{Context, TestAppContext};
|
||||
use indoc::indoc;
|
||||
use util::path;
|
||||
use workspace::Workspace;
|
||||
|
||||
#[gpui::test]
|
||||
|
@ -1551,13 +1552,13 @@ mod test {
|
|||
#[gpui::test]
|
||||
async fn test_command_write(cx: &mut TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
let path = Path::new("/root/dir/file.rs");
|
||||
let path = Path::new(path!("/root/dir/file.rs"));
|
||||
let fs = cx.workspace(|workspace, _, cx| workspace.project().read(cx).fs().clone());
|
||||
|
||||
cx.simulate_keystrokes("i @ escape");
|
||||
cx.simulate_keystrokes(": w enter");
|
||||
|
||||
assert_eq!(fs.load(path).await.unwrap(), "@\n");
|
||||
assert_eq!(fs.load(path).await.unwrap().replace("\r\n", "\n"), "@\n");
|
||||
|
||||
fs.as_fake().insert_file(path, b"oops\n".to_vec()).await;
|
||||
|
||||
|
@ -1567,12 +1568,12 @@ mod test {
|
|||
assert!(cx.has_pending_prompt());
|
||||
// "Cancel"
|
||||
cx.simulate_prompt_answer(0);
|
||||
assert_eq!(fs.load(path).await.unwrap(), "oops\n");
|
||||
assert_eq!(fs.load(path).await.unwrap().replace("\r\n", "\n"), "oops\n");
|
||||
assert!(!cx.has_pending_prompt());
|
||||
// force overwrite
|
||||
cx.simulate_keystrokes(": w ! enter");
|
||||
assert!(!cx.has_pending_prompt());
|
||||
assert_eq!(fs.load(path).await.unwrap(), "@@\n");
|
||||
assert_eq!(fs.load(path).await.unwrap().replace("\r\n", "\n"), "@@\n");
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
|
@ -1664,7 +1665,7 @@ mod test {
|
|||
let file_path = file.as_local().unwrap().abs_path(cx);
|
||||
|
||||
assert_eq!(text, expected_text);
|
||||
assert_eq!(file_path.to_str().unwrap(), expected_path);
|
||||
assert_eq!(file_path, Path::new(expected_path));
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
|
@ -1673,16 +1674,22 @@ mod test {
|
|||
|
||||
// Assert base state, that we're in /root/dir/file.rs
|
||||
cx.workspace(|workspace, _, cx| {
|
||||
assert_active_item(workspace, "/root/dir/file.rs", "", cx);
|
||||
assert_active_item(workspace, path!("/root/dir/file.rs"), "", cx);
|
||||
});
|
||||
|
||||
// Insert a new file
|
||||
let fs = cx.workspace(|workspace, _, cx| workspace.project().read(cx).fs().clone());
|
||||
fs.as_fake()
|
||||
.insert_file("/root/dir/file2.rs", "This is file2.rs".as_bytes().to_vec())
|
||||
.insert_file(
|
||||
path!("/root/dir/file2.rs"),
|
||||
"This is file2.rs".as_bytes().to_vec(),
|
||||
)
|
||||
.await;
|
||||
fs.as_fake()
|
||||
.insert_file("/root/dir/file3.rs", "go to file3".as_bytes().to_vec())
|
||||
.insert_file(
|
||||
path!("/root/dir/file3.rs"),
|
||||
"go to file3".as_bytes().to_vec(),
|
||||
)
|
||||
.await;
|
||||
|
||||
// Put the path to the second file into the currently open buffer
|
||||
|
@ -1694,7 +1701,12 @@ mod test {
|
|||
// We now have two items
|
||||
cx.workspace(|workspace, _, cx| assert_eq!(workspace.items(cx).count(), 2));
|
||||
cx.workspace(|workspace, _, cx| {
|
||||
assert_active_item(workspace, "/root/dir/file2.rs", "This is file2.rs", cx);
|
||||
assert_active_item(
|
||||
workspace,
|
||||
path!("/root/dir/file2.rs"),
|
||||
"This is file2.rs",
|
||||
cx,
|
||||
);
|
||||
});
|
||||
|
||||
// Update editor to point to `file2.rs`
|
||||
|
@ -1711,7 +1723,7 @@ mod test {
|
|||
// We now have three items
|
||||
cx.workspace(|workspace, _, cx| assert_eq!(workspace.items(cx).count(), 3));
|
||||
cx.workspace(|workspace, _, cx| {
|
||||
assert_active_item(workspace, "/root/dir/file3.rs", "go to file3", cx);
|
||||
assert_active_item(workspace, path!("/root/dir/file3.rs"), "go to file3", cx);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -696,12 +696,20 @@ mod test {
|
|||
|
||||
// not testing nvim as it doesn't have a filename
|
||||
cx.simulate_keystrokes("\" % p");
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
cx.assert_state(
|
||||
indoc! {"
|
||||
The quick brown
|
||||
dogdir/file.rˇs"},
|
||||
Mode::Normal,
|
||||
);
|
||||
#[cfg(target_os = "windows")]
|
||||
cx.assert_state(
|
||||
indoc! {"
|
||||
The quick brown
|
||||
dogdir\\file.rˇs"},
|
||||
Mode::Normal,
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
|
|
|
@ -1319,14 +1319,7 @@ impl LocalWorktree {
|
|||
let settings = self.settings.clone();
|
||||
let (scan_states_tx, mut scan_states_rx) = mpsc::unbounded();
|
||||
let background_scanner = cx.background_executor().spawn({
|
||||
let abs_path = &snapshot.abs_path;
|
||||
#[cfg(target_os = "windows")]
|
||||
let abs_path = abs_path
|
||||
.as_path()
|
||||
.canonicalize()
|
||||
.unwrap_or_else(|_| abs_path.as_path().to_path_buf());
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let abs_path = abs_path.as_path().to_path_buf();
|
||||
let abs_path = snapshot.abs_path.as_path().to_path_buf();
|
||||
let background = cx.background_executor().clone();
|
||||
async move {
|
||||
let (events, watcher) = fs.watch(&abs_path, FS_WATCH_LATENCY).await;
|
||||
|
|
|
@ -2156,7 +2156,13 @@ const CONFLICT: FileStatus = FileStatus::Unmerged(UnmergedStatus {
|
|||
second_head: UnmergedStatusCode::Updated,
|
||||
});
|
||||
|
||||
// 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
|
||||
#[gpui::test]
|
||||
#[cfg_attr(target_os = "windows", ignore)]
|
||||
async fn test_rename_work_directory(cx: &mut TestAppContext) {
|
||||
init_test(cx);
|
||||
cx.executor().allow_parking();
|
||||
|
@ -2184,7 +2190,7 @@ async fn test_rename_work_directory(cx: &mut TestAppContext) {
|
|||
let repo = git_init(&root_path.join("projects/project1"));
|
||||
git_add("a", &repo);
|
||||
git_commit("init", &repo);
|
||||
std::fs::write(root_path.join("projects/project1/a"), "aa").ok();
|
||||
std::fs::write(root_path.join("projects/project1/a"), "aa").unwrap();
|
||||
|
||||
cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete())
|
||||
.await;
|
||||
|
@ -2209,7 +2215,7 @@ async fn test_rename_work_directory(cx: &mut TestAppContext) {
|
|||
root_path.join("projects/project1"),
|
||||
root_path.join("projects/project2"),
|
||||
)
|
||||
.ok();
|
||||
.unwrap();
|
||||
tree.flush_fs_events(cx).await;
|
||||
|
||||
cx.read(|cx| {
|
||||
|
@ -2335,7 +2341,13 @@ async fn test_git_repository_for_path(cx: &mut 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
|
||||
#[gpui::test]
|
||||
#[cfg_attr(target_os = "windows", ignore)]
|
||||
async fn test_file_status(cx: &mut TestAppContext) {
|
||||
init_test(cx);
|
||||
cx.executor().allow_parking();
|
||||
|
|
|
@ -1569,6 +1569,7 @@ mod tests {
|
|||
time::Duration,
|
||||
};
|
||||
use theme::{ThemeRegistry, ThemeSettings};
|
||||
use util::{path, separator};
|
||||
use workspace::{
|
||||
item::{Item, ItemHandle},
|
||||
open_new, open_paths, pane, NewFile, OpenVisible, SaveIntent, SplitDirection,
|
||||
|
@ -1737,12 +1738,15 @@ mod tests {
|
|||
app_state
|
||||
.fs
|
||||
.as_fake()
|
||||
.insert_tree("/root", json!({"a": "hey", "b": "", "dir": {"c": "f"}}))
|
||||
.insert_tree(
|
||||
path!("/root"),
|
||||
json!({"a": "hey", "b": "", "dir": {"c": "f"}}),
|
||||
)
|
||||
.await;
|
||||
|
||||
cx.update(|cx| {
|
||||
open_paths(
|
||||
&[PathBuf::from("/root/dir")],
|
||||
&[PathBuf::from(path!("/root/dir"))],
|
||||
app_state.clone(),
|
||||
workspace::OpenOptions::default(),
|
||||
cx,
|
||||
|
@ -1754,7 +1758,7 @@ mod tests {
|
|||
|
||||
cx.update(|cx| {
|
||||
open_paths(
|
||||
&[PathBuf::from("/root/a")],
|
||||
&[PathBuf::from(path!("/root/a"))],
|
||||
app_state.clone(),
|
||||
workspace::OpenOptions {
|
||||
open_new_workspace: Some(false),
|
||||
|
@ -1769,7 +1773,7 @@ mod tests {
|
|||
|
||||
cx.update(|cx| {
|
||||
open_paths(
|
||||
&[PathBuf::from("/root/dir/c")],
|
||||
&[PathBuf::from(path!("/root/dir/c"))],
|
||||
app_state.clone(),
|
||||
workspace::OpenOptions {
|
||||
open_new_workspace: Some(true),
|
||||
|
@ -1789,12 +1793,15 @@ mod tests {
|
|||
app_state
|
||||
.fs
|
||||
.as_fake()
|
||||
.insert_tree("/root", json!({"dir1": {"a": "b"}, "dir2": {"c": "d"}}))
|
||||
.insert_tree(
|
||||
path!("/root"),
|
||||
json!({"dir1": {"a": "b"}, "dir2": {"c": "d"}}),
|
||||
)
|
||||
.await;
|
||||
|
||||
cx.update(|cx| {
|
||||
open_paths(
|
||||
&[PathBuf::from("/root/dir1/a")],
|
||||
&[PathBuf::from(path!("/root/dir1/a"))],
|
||||
app_state.clone(),
|
||||
workspace::OpenOptions::default(),
|
||||
cx,
|
||||
|
@ -1807,7 +1814,7 @@ mod tests {
|
|||
|
||||
cx.update(|cx| {
|
||||
open_paths(
|
||||
&[PathBuf::from("/root/dir2/c")],
|
||||
&[PathBuf::from(path!("/root/dir2/c"))],
|
||||
app_state.clone(),
|
||||
workspace::OpenOptions::default(),
|
||||
cx,
|
||||
|
@ -1819,7 +1826,7 @@ mod tests {
|
|||
|
||||
cx.update(|cx| {
|
||||
open_paths(
|
||||
&[PathBuf::from("/root/dir2")],
|
||||
&[PathBuf::from(path!("/root/dir2"))],
|
||||
app_state.clone(),
|
||||
workspace::OpenOptions::default(),
|
||||
cx,
|
||||
|
@ -1835,7 +1842,7 @@ mod tests {
|
|||
|
||||
cx.update(|cx| {
|
||||
open_paths(
|
||||
&[PathBuf::from("/root/dir2/c")],
|
||||
&[PathBuf::from(path!("/root/dir2/c"))],
|
||||
app_state.clone(),
|
||||
workspace::OpenOptions::default(),
|
||||
cx,
|
||||
|
@ -1864,12 +1871,12 @@ mod tests {
|
|||
app_state
|
||||
.fs
|
||||
.as_fake()
|
||||
.insert_tree("/root", json!({"a": "hey"}))
|
||||
.insert_tree(path!("/root"), json!({"a": "hey"}))
|
||||
.await;
|
||||
|
||||
cx.update(|cx| {
|
||||
open_paths(
|
||||
&[PathBuf::from("/root/a")],
|
||||
&[PathBuf::from(path!("/root/a"))],
|
||||
app_state.clone(),
|
||||
workspace::OpenOptions::default(),
|
||||
cx,
|
||||
|
@ -1951,7 +1958,7 @@ mod tests {
|
|||
// Opening the buffer again doesn't impact the window's edited state.
|
||||
cx.update(|cx| {
|
||||
open_paths(
|
||||
&[PathBuf::from("/root/a")],
|
||||
&[PathBuf::from(path!("/root/a"))],
|
||||
app_state,
|
||||
workspace::OpenOptions::default(),
|
||||
cx,
|
||||
|
@ -2013,12 +2020,12 @@ mod tests {
|
|||
app_state
|
||||
.fs
|
||||
.as_fake()
|
||||
.insert_tree("/root", json!({"a": "hey"}))
|
||||
.insert_tree(path!("/root"), json!({"a": "hey"}))
|
||||
.await;
|
||||
|
||||
cx.update(|cx| {
|
||||
open_paths(
|
||||
&[PathBuf::from("/root/a")],
|
||||
&[PathBuf::from(path!("/root/a"))],
|
||||
app_state.clone(),
|
||||
workspace::OpenOptions::default(),
|
||||
cx,
|
||||
|
@ -2070,7 +2077,7 @@ mod tests {
|
|||
// When we now reopen the window, the edited state and the edited buffer are back
|
||||
cx.update(|cx| {
|
||||
open_paths(
|
||||
&[PathBuf::from("/root/a")],
|
||||
&[PathBuf::from(path!("/root/a"))],
|
||||
app_state.clone(),
|
||||
workspace::OpenOptions::default(),
|
||||
cx,
|
||||
|
@ -2166,7 +2173,7 @@ mod tests {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
"a": {
|
||||
"file1": "contents 1",
|
||||
|
@ -2177,7 +2184,7 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
project.update(cx, |project, _cx| {
|
||||
project.languages().add(markdown_language())
|
||||
});
|
||||
|
@ -2298,7 +2305,7 @@ mod tests {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/",
|
||||
path!("/"),
|
||||
json!({
|
||||
"dir1": {
|
||||
"a.txt": ""
|
||||
|
@ -2316,7 +2323,7 @@ mod tests {
|
|||
|
||||
cx.update(|cx| {
|
||||
open_paths(
|
||||
&[PathBuf::from("/dir1/")],
|
||||
&[PathBuf::from(path!("/dir1/"))],
|
||||
app_state,
|
||||
workspace::OpenOptions::default(),
|
||||
cx,
|
||||
|
@ -2363,7 +2370,7 @@ mod tests {
|
|||
window
|
||||
.update(cx, |workspace, window, cx| {
|
||||
workspace.open_paths(
|
||||
vec!["/dir1/a.txt".into()],
|
||||
vec![path!("/dir1/a.txt").into()],
|
||||
OpenVisible::All,
|
||||
None,
|
||||
window,
|
||||
|
@ -2374,7 +2381,12 @@ mod tests {
|
|||
.await;
|
||||
cx.read(|cx| {
|
||||
let workspace = workspace.read(cx);
|
||||
assert_project_panel_selection(workspace, Path::new("/dir1"), Path::new("a.txt"), cx);
|
||||
assert_project_panel_selection(
|
||||
workspace,
|
||||
Path::new(path!("/dir1")),
|
||||
Path::new("a.txt"),
|
||||
cx,
|
||||
);
|
||||
assert_eq!(
|
||||
workspace
|
||||
.active_pane()
|
||||
|
@ -2393,7 +2405,7 @@ mod tests {
|
|||
window
|
||||
.update(cx, |workspace, window, cx| {
|
||||
workspace.open_paths(
|
||||
vec!["/dir2/b.txt".into()],
|
||||
vec![path!("/dir2/b.txt").into()],
|
||||
OpenVisible::All,
|
||||
None,
|
||||
window,
|
||||
|
@ -2404,14 +2416,19 @@ mod tests {
|
|||
.await;
|
||||
cx.read(|cx| {
|
||||
let workspace = workspace.read(cx);
|
||||
assert_project_panel_selection(workspace, Path::new("/dir2/b.txt"), Path::new(""), cx);
|
||||
assert_project_panel_selection(
|
||||
workspace,
|
||||
Path::new(path!("/dir2/b.txt")),
|
||||
Path::new(""),
|
||||
cx,
|
||||
);
|
||||
let worktree_roots = workspace
|
||||
.worktrees(cx)
|
||||
.map(|w| w.read(cx).as_local().unwrap().abs_path().as_ref())
|
||||
.collect::<HashSet<_>>();
|
||||
assert_eq!(
|
||||
worktree_roots,
|
||||
vec!["/dir1", "/dir2/b.txt"]
|
||||
vec![path!("/dir1"), path!("/dir2/b.txt")]
|
||||
.into_iter()
|
||||
.map(Path::new)
|
||||
.collect(),
|
||||
|
@ -2434,7 +2451,7 @@ mod tests {
|
|||
window
|
||||
.update(cx, |workspace, window, cx| {
|
||||
workspace.open_paths(
|
||||
vec!["/dir3".into(), "/dir3/c.txt".into()],
|
||||
vec![path!("/dir3").into(), path!("/dir3/c.txt").into()],
|
||||
OpenVisible::All,
|
||||
None,
|
||||
window,
|
||||
|
@ -2445,14 +2462,19 @@ mod tests {
|
|||
.await;
|
||||
cx.read(|cx| {
|
||||
let workspace = workspace.read(cx);
|
||||
assert_project_panel_selection(workspace, Path::new("/dir3"), Path::new("c.txt"), cx);
|
||||
assert_project_panel_selection(
|
||||
workspace,
|
||||
Path::new(path!("/dir3")),
|
||||
Path::new("c.txt"),
|
||||
cx,
|
||||
);
|
||||
let worktree_roots = workspace
|
||||
.worktrees(cx)
|
||||
.map(|w| w.read(cx).as_local().unwrap().abs_path().as_ref())
|
||||
.collect::<HashSet<_>>();
|
||||
assert_eq!(
|
||||
worktree_roots,
|
||||
vec!["/dir1", "/dir2/b.txt", "/dir3"]
|
||||
vec![path!("/dir1"), path!("/dir2/b.txt"), path!("/dir3")]
|
||||
.into_iter()
|
||||
.map(Path::new)
|
||||
.collect(),
|
||||
|
@ -2474,20 +2496,36 @@ mod tests {
|
|||
// Ensure opening invisibly a file outside an existing worktree adds a new, invisible worktree.
|
||||
window
|
||||
.update(cx, |workspace, window, cx| {
|
||||
workspace.open_paths(vec!["/d.txt".into()], OpenVisible::None, None, window, cx)
|
||||
workspace.open_paths(
|
||||
vec![path!("/d.txt").into()],
|
||||
OpenVisible::None,
|
||||
None,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.unwrap()
|
||||
.await;
|
||||
cx.read(|cx| {
|
||||
let workspace = workspace.read(cx);
|
||||
assert_project_panel_selection(workspace, Path::new("/d.txt"), Path::new(""), cx);
|
||||
assert_project_panel_selection(
|
||||
workspace,
|
||||
Path::new(path!("/d.txt")),
|
||||
Path::new(""),
|
||||
cx,
|
||||
);
|
||||
let worktree_roots = workspace
|
||||
.worktrees(cx)
|
||||
.map(|w| w.read(cx).as_local().unwrap().abs_path().as_ref())
|
||||
.collect::<HashSet<_>>();
|
||||
assert_eq!(
|
||||
worktree_roots,
|
||||
vec!["/dir1", "/dir2/b.txt", "/dir3", "/d.txt"]
|
||||
vec![
|
||||
path!("/dir1"),
|
||||
path!("/dir2/b.txt"),
|
||||
path!("/dir3"),
|
||||
path!("/d.txt")
|
||||
]
|
||||
.into_iter()
|
||||
.map(Path::new)
|
||||
.collect(),
|
||||
|
@ -2499,7 +2537,7 @@ mod tests {
|
|||
.collect::<HashSet<_>>();
|
||||
assert_eq!(
|
||||
visible_worktree_roots,
|
||||
vec!["/dir1", "/dir2/b.txt", "/dir3"]
|
||||
vec![path!("/dir1"), path!("/dir2/b.txt"), path!("/dir3")]
|
||||
.into_iter()
|
||||
.map(Path::new)
|
||||
.collect(),
|
||||
|
@ -2535,7 +2573,7 @@ mod tests {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
".gitignore": "ignored_dir\n",
|
||||
".git": {
|
||||
|
@ -2560,7 +2598,7 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
project.update(cx, |project, _cx| {
|
||||
project.languages().add(markdown_language())
|
||||
});
|
||||
|
@ -2569,9 +2607,9 @@ mod tests {
|
|||
|
||||
let initial_entries = cx.read(|cx| workspace.file_project_paths(cx));
|
||||
let paths_to_open = [
|
||||
Path::new("/root/excluded_dir/file").to_path_buf(),
|
||||
Path::new("/root/.git/HEAD").to_path_buf(),
|
||||
Path::new("/root/excluded_dir/ignored_subdir").to_path_buf(),
|
||||
PathBuf::from(path!("/root/excluded_dir/file")),
|
||||
PathBuf::from(path!("/root/.git/HEAD")),
|
||||
PathBuf::from(path!("/root/excluded_dir/ignored_subdir")),
|
||||
];
|
||||
let (opened_workspace, new_items) = cx
|
||||
.update(|cx| {
|
||||
|
@ -2616,8 +2654,8 @@ mod tests {
|
|||
opened_paths,
|
||||
vec![
|
||||
None,
|
||||
Some(".git/HEAD".to_string()),
|
||||
Some("excluded_dir/file".to_string()),
|
||||
Some(separator!(".git/HEAD").to_string()),
|
||||
Some(separator!("excluded_dir/file").to_string()),
|
||||
],
|
||||
"Excluded files should get opened, excluded dir should not get opened"
|
||||
);
|
||||
|
@ -2643,7 +2681,7 @@ mod tests {
|
|||
opened_buffer_paths.sort();
|
||||
assert_eq!(
|
||||
opened_buffer_paths,
|
||||
vec![".git/HEAD".to_string(), "excluded_dir/file".to_string()],
|
||||
vec![separator!(".git/HEAD").to_string(), separator!("excluded_dir/file").to_string()],
|
||||
"Despite not being present in the worktrees, buffers for excluded files are opened and added to the pane"
|
||||
);
|
||||
});
|
||||
|
@ -2655,10 +2693,10 @@ mod tests {
|
|||
app_state
|
||||
.fs
|
||||
.as_fake()
|
||||
.insert_tree("/root", json!({ "a.txt": "" }))
|
||||
.insert_tree(path!("/root"), json!({ "a.txt": "" }))
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
project.update(cx, |project, _cx| {
|
||||
project.languages().add(markdown_language())
|
||||
});
|
||||
|
@ -2669,7 +2707,7 @@ mod tests {
|
|||
window
|
||||
.update(cx, |workspace, window, cx| {
|
||||
workspace.open_paths(
|
||||
vec![PathBuf::from("/root/a.txt")],
|
||||
vec![PathBuf::from(path!("/root/a.txt"))],
|
||||
OpenVisible::All,
|
||||
None,
|
||||
window,
|
||||
|
@ -2693,7 +2731,7 @@ mod tests {
|
|||
app_state
|
||||
.fs
|
||||
.as_fake()
|
||||
.insert_file("/root/a.txt", b"changed".to_vec())
|
||||
.insert_file(path!("/root/a.txt"), b"changed".to_vec())
|
||||
.await;
|
||||
|
||||
cx.run_until_parked();
|
||||
|
@ -2721,9 +2759,13 @@ mod tests {
|
|||
#[gpui::test]
|
||||
async fn test_open_and_save_new_file(cx: &mut TestAppContext) {
|
||||
let app_state = init_test(cx);
|
||||
app_state.fs.create_dir(Path::new("/root")).await.unwrap();
|
||||
app_state
|
||||
.fs
|
||||
.create_dir(Path::new(path!("/root")))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
project.update(cx, |project, _| {
|
||||
project.languages().add(markdown_language());
|
||||
project.languages().add(rust_lang());
|
||||
|
@ -2766,7 +2808,7 @@ mod tests {
|
|||
.unwrap();
|
||||
cx.background_executor.run_until_parked();
|
||||
cx.simulate_new_path_selection(|parent_dir| {
|
||||
assert_eq!(parent_dir, Path::new("/root"));
|
||||
assert_eq!(parent_dir, Path::new(path!("/root")));
|
||||
Some(parent_dir.join("the-new-name.rs"))
|
||||
});
|
||||
cx.read(|cx| {
|
||||
|
@ -2922,7 +2964,7 @@ mod tests {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
"a": {
|
||||
"file1": "contents 1",
|
||||
|
@ -2933,7 +2975,7 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
project.update(cx, |project, _cx| {
|
||||
project.languages().add(markdown_language())
|
||||
});
|
||||
|
@ -3020,7 +3062,7 @@ mod tests {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
"a": {
|
||||
"file1": "contents 1\n".repeat(20),
|
||||
|
@ -3031,7 +3073,7 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
project.update(cx, |project, _cx| {
|
||||
project.languages().add(markdown_language())
|
||||
});
|
||||
|
@ -3262,7 +3304,7 @@ mod tests {
|
|||
.unwrap();
|
||||
app_state
|
||||
.fs
|
||||
.remove_file(Path::new("/root/a/file2"), Default::default())
|
||||
.remove_file(Path::new(path!("/root/a/file2")), Default::default())
|
||||
.await
|
||||
.unwrap();
|
||||
cx.background_executor.run_until_parked();
|
||||
|
@ -3403,7 +3445,7 @@ mod tests {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
"a": {
|
||||
"file1": "",
|
||||
|
@ -3415,7 +3457,7 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
project.update(cx, |project, _cx| {
|
||||
project.languages().add(markdown_language())
|
||||
});
|
||||
|
|
|
@ -535,6 +535,7 @@ mod tests {
|
|||
use editor::Editor;
|
||||
use gpui::TestAppContext;
|
||||
use serde_json::json;
|
||||
use util::path;
|
||||
use workspace::{AppState, Workspace};
|
||||
|
||||
use crate::zed::{open_listener::open_local_workspace, tests::init_test};
|
||||
|
@ -547,7 +548,7 @@ mod tests {
|
|||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
"dir1": {
|
||||
"file1.txt": "content1",
|
||||
|
@ -560,7 +561,7 @@ mod tests {
|
|||
assert_eq!(cx.windows().len(), 0);
|
||||
|
||||
// First open the workspace directory
|
||||
open_workspace_file("/root/dir1", None, app_state.clone(), cx).await;
|
||||
open_workspace_file(path!("/root/dir1"), None, app_state.clone(), cx).await;
|
||||
|
||||
assert_eq!(cx.windows().len(), 1);
|
||||
let workspace = cx.windows()[0].downcast::<Workspace>().unwrap();
|
||||
|
@ -571,7 +572,7 @@ mod tests {
|
|||
.unwrap();
|
||||
|
||||
// Now open a file inside that workspace
|
||||
open_workspace_file("/root/dir1/file1.txt", None, app_state.clone(), cx).await;
|
||||
open_workspace_file(path!("/root/dir1/file1.txt"), None, app_state.clone(), cx).await;
|
||||
|
||||
assert_eq!(cx.windows().len(), 1);
|
||||
workspace
|
||||
|
@ -581,7 +582,13 @@ mod tests {
|
|||
.unwrap();
|
||||
|
||||
// Now open a file inside that workspace, but tell Zed to open a new window
|
||||
open_workspace_file("/root/dir1/file1.txt", Some(true), app_state.clone(), cx).await;
|
||||
open_workspace_file(
|
||||
path!("/root/dir1/file1.txt"),
|
||||
Some(true),
|
||||
app_state.clone(),
|
||||
cx,
|
||||
)
|
||||
.await;
|
||||
|
||||
assert_eq!(cx.windows().len(), 2);
|
||||
|
||||
|
@ -599,12 +606,16 @@ mod tests {
|
|||
async fn test_open_workspace_with_nonexistent_files(cx: &mut TestAppContext) {
|
||||
let app_state = init_test(cx);
|
||||
|
||||
app_state.fs.as_fake().insert_tree("/root", json!({})).await;
|
||||
app_state
|
||||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(path!("/root"), json!({}))
|
||||
.await;
|
||||
|
||||
assert_eq!(cx.windows().len(), 0);
|
||||
|
||||
// Test case 1: Open a single file that does not exist yet
|
||||
open_workspace_file("/root/file5.txt", None, app_state.clone(), cx).await;
|
||||
open_workspace_file(path!("/root/file5.txt"), None, app_state.clone(), cx).await;
|
||||
|
||||
assert_eq!(cx.windows().len(), 1);
|
||||
let workspace_1 = cx.windows()[0].downcast::<Workspace>().unwrap();
|
||||
|
@ -616,7 +627,7 @@ mod tests {
|
|||
|
||||
// Test case 2: Open a single file that does not exist yet,
|
||||
// but tell Zed to add it to the current workspace
|
||||
open_workspace_file("/root/file6.txt", Some(false), app_state.clone(), cx).await;
|
||||
open_workspace_file(path!("/root/file6.txt"), Some(false), app_state.clone(), cx).await;
|
||||
|
||||
assert_eq!(cx.windows().len(), 1);
|
||||
workspace_1
|
||||
|
@ -628,7 +639,7 @@ mod tests {
|
|||
|
||||
// Test case 3: Open a single file that does not exist yet,
|
||||
// but tell Zed to NOT add it to the current workspace
|
||||
open_workspace_file("/root/file7.txt", Some(true), app_state.clone(), cx).await;
|
||||
open_workspace_file(path!("/root/file7.txt"), Some(true), app_state.clone(), cx).await;
|
||||
|
||||
assert_eq!(cx.windows().len(), 2);
|
||||
let workspace_2 = cx.windows()[1].downcast::<Workspace>().unwrap();
|
||||
|
|
22
script/exit-ci-if-dev-drive-is-full.ps1
Normal file
22
script/exit-ci-if-dev-drive-is-full.ps1
Normal file
|
@ -0,0 +1,22 @@
|
|||
param (
|
||||
[Parameter(Mandatory = $true)]
|
||||
[int]$MAX_SIZE_IN_GB
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$PSNativeCommandUseErrorActionPreference = $true
|
||||
$ProgressPreference = "SilentlyContinue"
|
||||
|
||||
if (-Not (Test-Path -Path "target")) {
|
||||
Write-Host "target directory does not exist yet"
|
||||
exit 0
|
||||
}
|
||||
|
||||
$current_size_gb = (Get-ChildItem -Recurse -Force -File -Path "target" | Measure-Object -Property Length -Sum).Sum / 1GB
|
||||
|
||||
Write-Host "target directory size: ${current_size_gb}GB. max size: ${MAX_SIZE_IN_GB}GB"
|
||||
|
||||
if ($current_size_gb -gt $MAX_SIZE_IN_GB) {
|
||||
Write-Host "Dev drive is almost full, increase the size first!"
|
||||
exit 1
|
||||
}
|
|
@ -3,7 +3,8 @@
|
|||
# The current version of the Windows runner is 10.0.20348 which does not support DevDrive option.
|
||||
# Ref: https://learn.microsoft.com/en-us/windows/dev-drive/
|
||||
|
||||
$Volume = New-VHD -Path C:/zed_dev_drive.vhdx -SizeBytes 30GB |
|
||||
# Currently, total CI requires almost 45GB of space, here we are creating a 60GB drive.
|
||||
$Volume = New-VHD -Path C:/zed_dev_drive.vhdx -SizeBytes 60GB |
|
||||
Mount-VHD -Passthru |
|
||||
Initialize-Disk -Passthru |
|
||||
New-Partition -AssignDriveLetter -UseMaximumSize |
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue