Add prettier tests infrastructure
This commit is contained in:
parent
4a88a9e253
commit
e50f4c0ee5
6 changed files with 139 additions and 17 deletions
|
@ -19,8 +19,8 @@ use gpui::{
|
||||||
use indoc::indoc;
|
use indoc::indoc;
|
||||||
use language::{
|
use language::{
|
||||||
language_settings::{AllLanguageSettings, AllLanguageSettingsContent, LanguageSettingsContent},
|
language_settings::{AllLanguageSettings, AllLanguageSettingsContent, LanguageSettingsContent},
|
||||||
BracketPairConfig, FakeLspAdapter, LanguageConfig, LanguageConfigOverride, LanguageRegistry,
|
BracketPairConfig, BundledFormatter, FakeLspAdapter, LanguageConfig, LanguageConfigOverride,
|
||||||
Override, Point,
|
LanguageRegistry, Override, Point,
|
||||||
};
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use project::project_settings::{LspSettings, ProjectSettings};
|
use project::project_settings::{LspSettings, ProjectSettings};
|
||||||
|
@ -7815,6 +7815,68 @@ async fn test_completions_in_languages_with_extra_word_characters(cx: &mut gpui:
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_document_format_with_prettier(cx: &mut gpui::TestAppContext) {
|
||||||
|
init_test(cx, |settings| {
|
||||||
|
settings.defaults.formatter = Some(language_settings::Formatter::Prettier)
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut language = Language::new(
|
||||||
|
LanguageConfig {
|
||||||
|
name: "Rust".into(),
|
||||||
|
path_suffixes: vec!["rs".to_string()],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
Some(tree_sitter_rust::language()),
|
||||||
|
);
|
||||||
|
|
||||||
|
let _ = language
|
||||||
|
.set_fake_lsp_adapter(Arc::new(FakeLspAdapter {
|
||||||
|
enabled_formatters: vec![BundledFormatter::Prettier {
|
||||||
|
parser_name: Some("test_parser"),
|
||||||
|
plugin_names: vec!["test_plugin"],
|
||||||
|
}],
|
||||||
|
..Default::default()
|
||||||
|
}))
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let fs = FakeFs::new(cx.background());
|
||||||
|
fs.insert_file("/file.rs", Default::default()).await;
|
||||||
|
|
||||||
|
// TODO kb have to specify some test node runtime
|
||||||
|
let project = Project::test(fs, ["/file.rs".as_ref()], cx).await;
|
||||||
|
project.update(cx, |project, _| project.languages().add(Arc::new(language)));
|
||||||
|
let buffer = project
|
||||||
|
.update(cx, |project, cx| project.open_local_buffer("/file.rs", cx))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||||
|
let editor = cx.add_window(|cx| build_editor(buffer, cx)).root(cx);
|
||||||
|
editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
|
||||||
|
|
||||||
|
let format = editor.update(cx, |editor, cx| {
|
||||||
|
editor.perform_format(project.clone(), FormatTrigger::Manual, cx)
|
||||||
|
});
|
||||||
|
format.await.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
editor.read_with(cx, |editor, cx| editor.text(cx)),
|
||||||
|
"one, two\nthree\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
|
||||||
|
let format = editor.update(cx, |editor, cx| {
|
||||||
|
editor.perform_format(project, FormatTrigger::Manual, cx)
|
||||||
|
});
|
||||||
|
cx.foreground().advance_clock(super::FORMAT_TIMEOUT);
|
||||||
|
cx.foreground().start_waiting();
|
||||||
|
format.await.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
editor.read_with(cx, |editor, cx| editor.text(cx)),
|
||||||
|
"one\ntwo\nthree\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn empty_range(row: usize, column: usize) -> Range<DisplayPoint> {
|
fn empty_range(row: usize, column: usize) -> Range<DisplayPoint> {
|
||||||
let point = DisplayPoint::new(row as u32, column as u32);
|
let point = DisplayPoint::new(row as u32, column as u32);
|
||||||
point..point
|
point..point
|
||||||
|
|
|
@ -498,6 +498,7 @@ pub struct FakeLspAdapter {
|
||||||
pub initializer: Option<Box<dyn 'static + Send + Sync + Fn(&mut lsp::FakeLanguageServer)>>,
|
pub initializer: Option<Box<dyn 'static + Send + Sync + Fn(&mut lsp::FakeLanguageServer)>>,
|
||||||
pub disk_based_diagnostics_progress_token: Option<String>,
|
pub disk_based_diagnostics_progress_token: Option<String>,
|
||||||
pub disk_based_diagnostics_sources: Vec<String>,
|
pub disk_based_diagnostics_sources: Vec<String>,
|
||||||
|
pub enabled_formatters: Vec<BundledFormatter>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
|
@ -1760,6 +1761,7 @@ impl Default for FakeLspAdapter {
|
||||||
disk_based_diagnostics_progress_token: None,
|
disk_based_diagnostics_progress_token: None,
|
||||||
initialization_options: None,
|
initialization_options: None,
|
||||||
disk_based_diagnostics_sources: Vec::new(),
|
disk_based_diagnostics_sources: Vec::new(),
|
||||||
|
enabled_formatters: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1816,6 +1818,10 @@ impl LspAdapter for Arc<FakeLspAdapter> {
|
||||||
async fn initialization_options(&self) -> Option<Value> {
|
async fn initialization_options(&self) -> Option<Value> {
|
||||||
self.initialization_options.clone()
|
self.initialization_options.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn enabled_formatters(&self) -> Vec<BundledFormatter> {
|
||||||
|
self.enabled_formatters.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_capture_indices(query: &Query, captures: &mut [(&str, &mut Option<u32>)]) {
|
fn get_capture_indices(query: &Query, captures: &mut [(&str, &mut Option<u32>)]) {
|
||||||
|
|
|
@ -230,19 +230,32 @@ impl FakeNodeRuntime {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl NodeRuntime for FakeNodeRuntime {
|
impl NodeRuntime for FakeNodeRuntime {
|
||||||
async fn binary_path(&self) -> Result<PathBuf> {
|
async fn binary_path(&self) -> anyhow::Result<PathBuf> {
|
||||||
unreachable!()
|
// TODO kb move away into a separate type + a Project's setter (for test code)
|
||||||
|
Ok(PathBuf::from("prettier_fake_node"))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_npm_subcommand(&self, _: Option<&Path>, _: &str, _: &[&str]) -> Result<Output> {
|
async fn run_npm_subcommand(&self, _: Option<&Path>, _: &str, _: &[&str]) -> Result<Output> {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn npm_package_latest_version(&self, _: &str) -> Result<String> {
|
async fn npm_package_latest_version(&self, name: &str) -> anyhow::Result<String> {
|
||||||
unreachable!()
|
if name == "prettier" {
|
||||||
|
Ok("0.0.1".to_string())
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn npm_install_packages(&self, _: &Path, _: &[(&str, &str)]) -> Result<()> {
|
async fn npm_install_packages(
|
||||||
unreachable!()
|
&self,
|
||||||
|
_: &Path,
|
||||||
|
packages: &[(&str, &str)],
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
if packages == [("prettier", "0.0.1")] {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,9 @@ edition = "2021"
|
||||||
[lib]
|
[lib]
|
||||||
path = "src/prettier.rs"
|
path = "src/prettier.rs"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
test-support = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
client = { path = "../client" }
|
client = { path = "../client" }
|
||||||
collections = { path = "../collections"}
|
collections = { path = "../collections"}
|
||||||
|
|
|
@ -11,7 +11,7 @@ use language::language_settings::language_settings;
|
||||||
use language::proto::deserialize_diff;
|
use language::proto::deserialize_diff;
|
||||||
use language::{Buffer, BundledFormatter, Diff};
|
use language::{Buffer, BundledFormatter, Diff};
|
||||||
use lsp::request::Request;
|
use lsp::request::Request;
|
||||||
use lsp::{LanguageServer, LanguageServerBinary, LanguageServerId};
|
use lsp::{LanguageServer, LanguageServerId};
|
||||||
use node_runtime::NodeRuntime;
|
use node_runtime::NodeRuntime;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use util::paths::DEFAULT_PRETTIER_DIR;
|
use util::paths::DEFAULT_PRETTIER_DIR;
|
||||||
|
@ -19,6 +19,8 @@ use util::paths::DEFAULT_PRETTIER_DIR;
|
||||||
pub enum Prettier {
|
pub enum Prettier {
|
||||||
Local(Local),
|
Local(Local),
|
||||||
Remote(Remote),
|
Remote(Remote),
|
||||||
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
|
Test(TestPrettier),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Local {
|
pub struct Local {
|
||||||
|
@ -35,6 +37,13 @@ pub struct Remote {
|
||||||
client: Arc<Client>,
|
client: Arc<Client>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
|
pub struct TestPrettier {
|
||||||
|
worktree_id: Option<usize>,
|
||||||
|
prettier_dir: PathBuf,
|
||||||
|
default: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct LocateStart {
|
pub struct LocateStart {
|
||||||
pub worktree_root_path: Arc<Path>,
|
pub worktree_root_path: Arc<Path>,
|
||||||
|
@ -180,6 +189,22 @@ impl Prettier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
|
pub async fn start(
|
||||||
|
worktree_id: Option<usize>,
|
||||||
|
_: LanguageServerId,
|
||||||
|
prettier_dir: PathBuf,
|
||||||
|
_: Arc<dyn NodeRuntime>,
|
||||||
|
_: AsyncAppContext,
|
||||||
|
) -> anyhow::Result<Self> {
|
||||||
|
Ok(Self::Test(TestPrettier {
|
||||||
|
worktree_id,
|
||||||
|
default: prettier_dir == DEFAULT_PRETTIER_DIR.as_path(),
|
||||||
|
prettier_dir,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(test, feature = "test-support")))]
|
||||||
pub async fn start(
|
pub async fn start(
|
||||||
worktree_id: Option<usize>,
|
worktree_id: Option<usize>,
|
||||||
server_id: LanguageServerId,
|
server_id: LanguageServerId,
|
||||||
|
@ -400,6 +425,12 @@ impl Prettier {
|
||||||
.diff
|
.diff
|
||||||
.map(deserialize_diff)
|
.map(deserialize_diff)
|
||||||
.context("missing diff after prettier diff invocation"),
|
.context("missing diff after prettier diff invocation"),
|
||||||
|
Self::Test(_) => Ok(buffer
|
||||||
|
.read_with(cx, |buffer, cx| {
|
||||||
|
let formatted_text = buffer.text() + "\nformatted by test prettier";
|
||||||
|
buffer.diff(formatted_text, cx)
|
||||||
|
})
|
||||||
|
.await),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,34 +458,39 @@ impl Prettier {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.context("prettier invoke clear cache"),
|
.context("prettier invoke clear cache"),
|
||||||
|
Self::Test(_) => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn server(&self) -> Option<&Arc<LanguageServer>> {
|
pub fn server(&self) -> Option<&Arc<LanguageServer>> {
|
||||||
match self {
|
match self {
|
||||||
Prettier::Local(local) => Some(&local.server),
|
Self::Local(local) => Some(&local.server),
|
||||||
Prettier::Remote(_) => None,
|
Self::Remote(_) => None,
|
||||||
|
Self::Test(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_default(&self) -> bool {
|
pub fn is_default(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Prettier::Local(local) => local.default,
|
Self::Local(local) => local.default,
|
||||||
Prettier::Remote(_) => false,
|
Self::Remote(_) => false,
|
||||||
|
Self::Test(test_prettier) => test_prettier.default,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prettier_dir(&self) -> &Path {
|
pub fn prettier_dir(&self) -> &Path {
|
||||||
match self {
|
match self {
|
||||||
Prettier::Local(local) => &local.prettier_dir,
|
Self::Local(local) => &local.prettier_dir,
|
||||||
Prettier::Remote(remote) => &remote.prettier_dir,
|
Self::Remote(remote) => &remote.prettier_dir,
|
||||||
|
Self::Test(test_prettier) => &test_prettier.prettier_dir,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn worktree_id(&self) -> Option<usize> {
|
pub fn worktree_id(&self) -> Option<usize> {
|
||||||
match self {
|
match self {
|
||||||
Prettier::Local(local) => local.worktree_id,
|
Self::Local(local) => local.worktree_id,
|
||||||
Prettier::Remote(remote) => remote.worktree_id,
|
Self::Remote(remote) => remote.worktree_id,
|
||||||
|
Self::Test(test_prettier) => test_prettier.worktree_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ test-support = [
|
||||||
"language/test-support",
|
"language/test-support",
|
||||||
"settings/test-support",
|
"settings/test-support",
|
||||||
"text/test-support",
|
"text/test-support",
|
||||||
|
"prettier/test-support",
|
||||||
]
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -75,6 +76,7 @@ gpui = { path = "../gpui", features = ["test-support"] }
|
||||||
language = { path = "../language", features = ["test-support"] }
|
language = { path = "../language", features = ["test-support"] }
|
||||||
lsp = { path = "../lsp", features = ["test-support"] }
|
lsp = { path = "../lsp", features = ["test-support"] }
|
||||||
settings = { path = "../settings", features = ["test-support"] }
|
settings = { path = "../settings", features = ["test-support"] }
|
||||||
|
prettier = { path = "../prettier", features = ["test-support"] }
|
||||||
util = { path = "../util", features = ["test-support"] }
|
util = { path = "../util", features = ["test-support"] }
|
||||||
rpc = { path = "../rpc", features = ["test-support"] }
|
rpc = { path = "../rpc", features = ["test-support"] }
|
||||||
git2.workspace = true
|
git2.workspace = true
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue