Detailed changes
@@ -7830,11 +7830,12 @@ async fn test_document_format_with_prettier(cx: &mut gpui::TestAppContext) {
Some(tree_sitter_rust::language()),
);
+ let test_plugin = "test_plugin";
let _ = language
.set_fake_lsp_adapter(Arc::new(FakeLspAdapter {
enabled_formatters: vec![BundledFormatter::Prettier {
parser_name: Some("test_parser"),
- plugin_names: vec!["test_plugin"],
+ plugin_names: vec![test_plugin],
}],
..Default::default()
}))
@@ -7843,37 +7844,31 @@ async fn test_document_format_with_prettier(cx: &mut gpui::TestAppContext) {
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 prettier_format_suffix = project.update(cx, |project, _| {
+ let suffix = project.enable_test_prettier(&[test_plugin]);
+ project.languages().add(Arc::new(language));
+ suffix
+ });
let buffer = project
.update(cx, |project, cx| project.open_local_buffer("/file.rs", cx))
.await
.unwrap();
+ let buffer_text = "one\ntwo\nthree\n";
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));
+ editor.update(cx, |editor, cx| editor.set_text(buffer_text, 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"
+ buffer_text.to_string() + prettier_format_suffix,
+ "Test prettier formatting was not applied to the original buffer text",
);
}
@@ -220,18 +220,83 @@ impl NodeRuntime for RealNodeRuntime {
}
}
-pub struct FakeNodeRuntime;
+pub struct FakeNodeRuntime(Option<PrettierSupport>);
+
+struct PrettierSupport {
+ plugins: Vec<&'static str>,
+}
impl FakeNodeRuntime {
pub fn new() -> Arc<dyn NodeRuntime> {
- Arc::new(FakeNodeRuntime)
+ Arc::new(FakeNodeRuntime(None))
+ }
+
+ pub fn with_prettier_support(plugins: &[&'static str]) -> Arc<dyn NodeRuntime> {
+ Arc::new(FakeNodeRuntime(Some(PrettierSupport::new(plugins))))
}
}
#[async_trait::async_trait]
impl NodeRuntime for FakeNodeRuntime {
async fn binary_path(&self) -> anyhow::Result<PathBuf> {
- // TODO kb move away into a separate type + a Project's setter (for test code)
+ if let Some(prettier_support) = &self.0 {
+ prettier_support.binary_path().await
+ } else {
+ unreachable!()
+ }
+ }
+
+ async fn run_npm_subcommand(
+ &self,
+ directory: Option<&Path>,
+ subcommand: &str,
+ args: &[&str],
+ ) -> anyhow::Result<Output> {
+ if let Some(prettier_support) = &self.0 {
+ prettier_support
+ .run_npm_subcommand(directory, subcommand, args)
+ .await
+ } else {
+ unreachable!()
+ }
+ }
+
+ async fn npm_package_latest_version(&self, name: &str) -> anyhow::Result<String> {
+ if let Some(prettier_support) = &self.0 {
+ prettier_support.npm_package_latest_version(name).await
+ } else {
+ unreachable!()
+ }
+ }
+
+ async fn npm_install_packages(
+ &self,
+ directory: &Path,
+ packages: &[(&str, &str)],
+ ) -> anyhow::Result<()> {
+ if let Some(prettier_support) = &self.0 {
+ prettier_support
+ .npm_install_packages(directory, packages)
+ .await
+ } else {
+ unreachable!()
+ }
+ }
+}
+
+impl PrettierSupport {
+ const PACKAGE_VERSION: &str = "0.0.1";
+
+ fn new(plugins: &[&'static str]) -> Self {
+ Self {
+ plugins: plugins.to_vec(),
+ }
+ }
+}
+
+#[async_trait::async_trait]
+impl NodeRuntime for PrettierSupport {
+ async fn binary_path(&self) -> anyhow::Result<PathBuf> {
Ok(PathBuf::from("prettier_fake_node"))
}
@@ -240,10 +305,10 @@ impl NodeRuntime for FakeNodeRuntime {
}
async fn npm_package_latest_version(&self, name: &str) -> anyhow::Result<String> {
- if name == "prettier" {
- Ok("0.0.1".to_string())
+ if name == "prettier" || self.plugins.contains(&name) {
+ Ok(Self::PACKAGE_VERSION.to_string())
} else {
- unreachable!("Unexpected package name: {name}")
+ panic!("Unexpected package name: {name}")
}
}
@@ -252,10 +317,32 @@ impl NodeRuntime for FakeNodeRuntime {
_: &Path,
packages: &[(&str, &str)],
) -> anyhow::Result<()> {
- if packages == [("prettier", "0.0.1")] {
- Ok(())
- } else {
- unreachable!("Unexpected packages to install: {packages:?}")
+ assert_eq!(
+ packages.len(),
+ self.plugins.len() + 1,
+ "Unexpected packages length to install: {:?}, expected `prettier` + {:?}",
+ packages,
+ self.plugins
+ );
+ for (name, version) in packages {
+ assert!(
+ name == &"prettier" || self.plugins.contains(name),
+ "Unexpected package `{}` to install in packages {:?}, expected {} for `prettier` + {:?}",
+ name,
+ packages,
+ Self::PACKAGE_VERSION,
+ self.plugins
+ );
+ assert_eq!(
+ version,
+ &Self::PACKAGE_VERSION,
+ "Unexpected package version `{}` to install in packages {:?}, expected {} for `prettier` + {:?}",
+ version,
+ packages,
+ Self::PACKAGE_VERSION,
+ self.plugins
+ );
}
+ Ok(())
}
}
@@ -71,6 +71,9 @@ impl Prettier {
".editorconfig",
];
+ #[cfg(any(test, feature = "test-support"))]
+ pub const FORMAT_SUFFIX: &str = "\nformatted by test prettier";
+
pub fn remote(
project_id: u64,
worktree_id: Option<usize>,
@@ -433,7 +436,7 @@ impl Prettier {
#[cfg(any(test, feature = "test-support"))]
Self::Test(_) => Ok(buffer
.read_with(cx, |buffer, cx| {
- let formatted_text = buffer.text() + "\nformatted by test prettier";
+ let formatted_text = buffer.text() + Self::FORMAT_SUFFIX;
buffer.diff(formatted_text, cx)
})
.await),
@@ -837,6 +837,16 @@ impl Project {
project
}
+ /// Enables a prettier mock that avoids interacting with node runtime, prettier LSP wrapper, or any real file changes.
+ /// Instead, if appends the suffix to every input, this suffix is returned by this method.
+ #[cfg(any(test, feature = "test-support"))]
+ pub fn enable_test_prettier(&mut self, plugins: &[&'static str]) -> &'static str {
+ self.node = Some(node_runtime::FakeNodeRuntime::with_prettier_support(
+ plugins,
+ ));
+ Prettier::FORMAT_SUFFIX
+ }
+
fn on_settings_changed(&mut self, cx: &mut ModelContext<Self>) {
let mut language_servers_to_start = Vec::new();
let mut language_formatters_to_check = Vec::new();
@@ -8442,7 +8452,7 @@ impl Project {
return Some(existing_prettier);
}
- log::info!("Found prettier at {prettier_dir:?}, starting.");
+ log::info!("Found prettier in {prettier_dir:?}, starting.");
let task_prettier_dir = prettier_dir.clone();
let weak_project = this.downgrade();
let new_server_id =
@@ -8459,7 +8469,7 @@ impl Project {
.await
.context("prettier start")
.map_err(Arc::new)?;
- log::info!("Had started prettier in {:?}", prettier.prettier_dir());
+ log::info!("Started prettier in {:?}", prettier.prettier_dir());
if let Some((project, prettier_server)) =
weak_project.upgrade(&mut cx).zip(prettier.server())