mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
fix(lsp): include all diagnosable documents on initialize (#17979)
Closes https://github.com/denoland/vscode_deno/issues/797 Closes https://github.com/denoland/deno/issues/11190 Closes https://github.com/denoland/vscode_deno/issues/811 Closes https://github.com/denoland/vscode_deno/issues/761 Closes https://github.com/denoland/vscode_deno/issues/585 Closes https://github.com/denoland/vscode_deno/issues/561 Closes https://github.com/denoland/vscode_deno/issues/410
This commit is contained in:
parent
5949321c55
commit
5d20c36eaf
12 changed files with 813 additions and 247 deletions
3
cli/cache/http_cache.rs
vendored
3
cli/cache/http_cache.rs
vendored
|
@ -11,7 +11,6 @@ use deno_core::serde::Deserialize;
|
|||
use deno_core::serde::Serialize;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::url::Url;
|
||||
use log::error;
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
|
@ -42,7 +41,7 @@ fn base_url_to_filename(url: &Url) -> Option<PathBuf> {
|
|||
}
|
||||
"data" | "blob" => (),
|
||||
scheme => {
|
||||
error!("Don't know how to create cache name for scheme: {}", scheme);
|
||||
log::debug!("Don't know how to create cache name for scheme: {}", scheme);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -485,6 +485,31 @@ impl Config {
|
|||
.unwrap_or_else(|| self.settings.workspace.enable)
|
||||
}
|
||||
|
||||
/// Gets the root directories or file paths based on the workspace config.
|
||||
pub fn enabled_root_urls(&self) -> Vec<Url> {
|
||||
let mut urls: Vec<Url> = Vec::new();
|
||||
|
||||
if !self.settings.workspace.enable && self.enabled_paths.is_empty() {
|
||||
// do not return any urls when disabled
|
||||
return urls;
|
||||
}
|
||||
|
||||
for (workspace, enabled_paths) in &self.enabled_paths {
|
||||
if !enabled_paths.is_empty() {
|
||||
urls.extend(enabled_paths.iter().cloned());
|
||||
} else {
|
||||
urls.push(workspace.clone());
|
||||
}
|
||||
}
|
||||
if urls.is_empty() {
|
||||
if let Some(root_dir) = &self.root_uri {
|
||||
urls.push(root_dir.clone())
|
||||
}
|
||||
}
|
||||
sort_and_remove_non_leaf_urls(&mut urls);
|
||||
urls
|
||||
}
|
||||
|
||||
pub fn specifier_code_lens_test(&self, specifier: &ModuleSpecifier) -> bool {
|
||||
let value = self
|
||||
.settings
|
||||
|
@ -621,6 +646,21 @@ impl Config {
|
|||
}
|
||||
}
|
||||
|
||||
/// Removes any URLs that are a descendant of another URL in the collection.
|
||||
fn sort_and_remove_non_leaf_urls(dirs: &mut Vec<Url>) {
|
||||
if dirs.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
dirs.sort();
|
||||
for i in (0..dirs.len() - 1).rev() {
|
||||
let prev = &dirs[i + 1];
|
||||
if prev.as_str().starts_with(dirs[i].as_str()) {
|
||||
dirs.remove(i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -785,4 +825,69 @@ mod tests {
|
|||
WorkspaceSettings::default()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sort_and_remove_non_leaf_urls() {
|
||||
fn run_test(dirs: Vec<&str>, expected_output: Vec<&str>) {
|
||||
let mut dirs = dirs
|
||||
.into_iter()
|
||||
.map(|dir| Url::parse(dir).unwrap())
|
||||
.collect();
|
||||
sort_and_remove_non_leaf_urls(&mut dirs);
|
||||
let dirs: Vec<_> = dirs.iter().map(|dir| dir.as_str()).collect();
|
||||
assert_eq!(dirs, expected_output);
|
||||
}
|
||||
|
||||
run_test(
|
||||
vec![
|
||||
"file:///test/asdf/test/asdf/",
|
||||
"file:///test/asdf/",
|
||||
"file:///test/asdf/",
|
||||
"file:///testing/456/893/",
|
||||
"file:///testing/456/893/test/",
|
||||
],
|
||||
vec!["file:///test/asdf/", "file:///testing/456/893/"],
|
||||
);
|
||||
run_test(vec![], vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_enabled_root_urls() {
|
||||
let mut config = Config::new();
|
||||
let root_dir = Url::parse("file:///example/").unwrap();
|
||||
config.root_uri = Some(root_dir.clone());
|
||||
config.settings.workspace.enable = false;
|
||||
config.settings.workspace.enable_paths = Vec::new();
|
||||
assert_eq!(config.enabled_root_urls(), vec![]);
|
||||
|
||||
config.settings.workspace.enable = true;
|
||||
assert_eq!(config.enabled_root_urls(), vec![root_dir]);
|
||||
|
||||
config.settings.workspace.enable = false;
|
||||
let root_dir1 = Url::parse("file:///root1/").unwrap();
|
||||
let root_dir2 = Url::parse("file:///root2/").unwrap();
|
||||
let root_dir3 = Url::parse("file:///root3/").unwrap();
|
||||
config.enabled_paths = HashMap::from([
|
||||
(
|
||||
root_dir1.clone(),
|
||||
vec![
|
||||
root_dir1.join("sub_dir").unwrap(),
|
||||
root_dir1.join("sub_dir/other").unwrap(),
|
||||
root_dir1.join("test.ts").unwrap(),
|
||||
],
|
||||
),
|
||||
(root_dir2.clone(), vec![root_dir2.join("other.ts").unwrap()]),
|
||||
(root_dir3.clone(), vec![]),
|
||||
]);
|
||||
|
||||
assert_eq!(
|
||||
config.enabled_root_urls(),
|
||||
vec![
|
||||
root_dir1.join("sub_dir").unwrap(),
|
||||
root_dir1.join("test.ts").unwrap(),
|
||||
root_dir2.join("other.ts").unwrap(),
|
||||
root_dir3
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,11 +43,13 @@ use deno_runtime::deno_node::NodeResolutionMode;
|
|||
use deno_runtime::deno_node::PackageJson;
|
||||
use deno_runtime::permissions::PermissionsContainer;
|
||||
use indexmap::IndexMap;
|
||||
use lsp::Url;
|
||||
use once_cell::sync::Lazy;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::collections::VecDeque;
|
||||
use std::fs;
|
||||
use std::fs::ReadDir;
|
||||
use std::ops::Range;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
@ -775,18 +777,6 @@ impl FileSystemDocuments {
|
|||
self.docs.insert(specifier.clone(), doc.clone());
|
||||
Some(doc)
|
||||
}
|
||||
|
||||
pub fn refresh_dependencies(
|
||||
&mut self,
|
||||
resolver: &dyn deno_graph::source::Resolver,
|
||||
) {
|
||||
for doc in self.docs.values_mut() {
|
||||
if let Some(new_doc) = doc.maybe_with_new_resolver(resolver) {
|
||||
*doc = new_doc;
|
||||
}
|
||||
}
|
||||
self.dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn get_document_path(
|
||||
|
@ -1166,6 +1156,7 @@ impl Documents {
|
|||
|
||||
pub fn update_config(
|
||||
&mut self,
|
||||
root_urls: Vec<Url>,
|
||||
maybe_import_map: Option<Arc<import_map::ImportMap>>,
|
||||
maybe_config_file: Option<&ConfigFile>,
|
||||
maybe_package_json: Option<&PackageJson>,
|
||||
|
@ -1173,11 +1164,18 @@ impl Documents {
|
|||
npm_resolution: NpmResolution,
|
||||
) {
|
||||
fn calculate_resolver_config_hash(
|
||||
root_urls: &[Url],
|
||||
maybe_import_map: Option<&import_map::ImportMap>,
|
||||
maybe_jsx_config: Option<&JsxImportSourceConfig>,
|
||||
maybe_package_json_deps: Option<&PackageJsonDeps>,
|
||||
) -> u64 {
|
||||
let mut hasher = FastInsecureHasher::default();
|
||||
hasher.write_hashable(&{
|
||||
// ensure these are sorted (they should be, but this is a safeguard)
|
||||
let mut root_urls = root_urls.to_vec();
|
||||
root_urls.sort_unstable();
|
||||
root_urls
|
||||
});
|
||||
if let Some(import_map) = maybe_import_map {
|
||||
hasher.write_str(&import_map.to_json());
|
||||
hasher.write_str(import_map.base_url().as_str());
|
||||
|
@ -1193,6 +1191,7 @@ impl Documents {
|
|||
let maybe_jsx_config =
|
||||
maybe_config_file.and_then(|cf| cf.to_maybe_jsx_import_source_config());
|
||||
let new_resolver_config_hash = calculate_resolver_config_hash(
|
||||
&root_urls,
|
||||
maybe_import_map.as_deref(),
|
||||
maybe_jsx_config.as_ref(),
|
||||
maybe_package_json_deps.as_ref(),
|
||||
|
@ -1232,21 +1231,51 @@ impl Documents {
|
|||
|
||||
// only refresh the dependencies if the underlying configuration has changed
|
||||
if self.resolver_config_hash != new_resolver_config_hash {
|
||||
self.refresh_dependencies();
|
||||
self.refresh_dependencies(root_urls);
|
||||
self.resolver_config_hash = new_resolver_config_hash;
|
||||
}
|
||||
|
||||
self.dirty = true;
|
||||
}
|
||||
|
||||
fn refresh_dependencies(&mut self) {
|
||||
fn refresh_dependencies(&mut self, root_urls: Vec<Url>) {
|
||||
let resolver = self.resolver.as_graph_resolver();
|
||||
for doc in self.open_docs.values_mut() {
|
||||
if let Some(new_doc) = doc.maybe_with_new_resolver(resolver) {
|
||||
*doc = new_doc;
|
||||
}
|
||||
}
|
||||
self.file_system_docs.lock().refresh_dependencies(resolver);
|
||||
|
||||
// update the file system documents
|
||||
let mut fs_docs = self.file_system_docs.lock();
|
||||
let mut not_found_docs =
|
||||
fs_docs.docs.keys().cloned().collect::<HashSet<_>>();
|
||||
let open_docs = &mut self.open_docs;
|
||||
|
||||
for specifier in PreloadDocumentFinder::from_root_urls(&root_urls) {
|
||||
// mark this document as having been found
|
||||
not_found_docs.remove(&specifier);
|
||||
|
||||
if !open_docs.contains_key(&specifier)
|
||||
&& !fs_docs.docs.contains_key(&specifier)
|
||||
{
|
||||
fs_docs.refresh_document(&self.cache, resolver, &specifier);
|
||||
} else {
|
||||
// update the existing entry to have the new resolver
|
||||
if let Some(doc) = fs_docs.docs.get_mut(&specifier) {
|
||||
if let Some(new_doc) = doc.maybe_with_new_resolver(resolver) {
|
||||
*doc = new_doc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clean up and remove any documents that weren't found
|
||||
for uri in not_found_docs {
|
||||
fs_docs.docs.remove(&uri);
|
||||
}
|
||||
|
||||
fs_docs.dirty = true;
|
||||
}
|
||||
|
||||
/// Iterate through the documents, building a map where the key is a unique
|
||||
|
@ -1478,12 +1507,150 @@ fn analyze_module(
|
|||
}
|
||||
}
|
||||
|
||||
/// Iterator that finds documents that can be preloaded into
|
||||
/// the LSP on startup.
|
||||
struct PreloadDocumentFinder {
|
||||
pending_dirs: Vec<PathBuf>,
|
||||
pending_files: Vec<PathBuf>,
|
||||
current_entries: Option<ReadDir>,
|
||||
}
|
||||
|
||||
impl PreloadDocumentFinder {
|
||||
pub fn from_root_urls(root_urls: &Vec<Url>) -> Self {
|
||||
let mut finder = PreloadDocumentFinder {
|
||||
pending_dirs: Default::default(),
|
||||
pending_files: Default::default(),
|
||||
current_entries: Default::default(),
|
||||
};
|
||||
for root_url in root_urls {
|
||||
if let Ok(path) = root_url.to_file_path() {
|
||||
if path.is_dir() {
|
||||
finder.pending_dirs.push(path);
|
||||
} else {
|
||||
finder.pending_files.push(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
finder
|
||||
}
|
||||
|
||||
fn read_next_file_entry(&mut self) -> Option<ModuleSpecifier> {
|
||||
fn is_discoverable_dir(dir_path: &Path) -> bool {
|
||||
if let Some(dir_name) = dir_path.file_name() {
|
||||
let dir_name = dir_name.to_string_lossy().to_lowercase();
|
||||
!matches!(dir_name.as_str(), "node_modules" | ".git")
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(mut entries) = self.current_entries.take() {
|
||||
while let Some(entry) = entries.next() {
|
||||
if let Ok(entry) = entry {
|
||||
let path = entry.path();
|
||||
if let Ok(file_type) = entry.file_type() {
|
||||
if file_type.is_dir() && is_discoverable_dir(&path) {
|
||||
self.pending_dirs.push(path);
|
||||
} else if file_type.is_file() {
|
||||
if let Some(specifier) = Self::get_valid_specifier(&path) {
|
||||
// restore the next entries for next time
|
||||
self.current_entries = Some(entries);
|
||||
return Some(specifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn get_valid_specifier(path: &Path) -> Option<ModuleSpecifier> {
|
||||
fn is_discoverable_file(file_path: &Path) -> bool {
|
||||
// Don't auto-discover minified files as they are likely to be very large
|
||||
// and likely not to have dependencies on code outside them that would
|
||||
// be useful in the LSP
|
||||
if let Some(file_name) = file_path.file_name() {
|
||||
let file_name = file_name.to_string_lossy().to_lowercase();
|
||||
!file_name.as_str().contains(".min.")
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_discoverable_media_type(media_type: MediaType) -> bool {
|
||||
match media_type {
|
||||
MediaType::JavaScript
|
||||
| MediaType::Jsx
|
||||
| MediaType::Mjs
|
||||
| MediaType::Cjs
|
||||
| MediaType::TypeScript
|
||||
| MediaType::Mts
|
||||
| MediaType::Cts
|
||||
| MediaType::Dts
|
||||
| MediaType::Dmts
|
||||
| MediaType::Dcts
|
||||
| MediaType::Tsx => true,
|
||||
MediaType::Json // ignore because json never depends on other files
|
||||
| MediaType::Wasm
|
||||
| MediaType::SourceMap
|
||||
| MediaType::TsBuildInfo
|
||||
| MediaType::Unknown => false,
|
||||
}
|
||||
}
|
||||
|
||||
let media_type = MediaType::from_path(path);
|
||||
if is_discoverable_media_type(media_type) && is_discoverable_file(path) {
|
||||
if let Ok(specifier) = ModuleSpecifier::from_file_path(path) {
|
||||
return Some(specifier);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn queue_next_file_entries(&mut self) {
|
||||
debug_assert!(self.current_entries.is_none());
|
||||
while let Some(dir_path) = self.pending_dirs.pop() {
|
||||
if let Ok(entries) = fs::read_dir(&dir_path) {
|
||||
self.current_entries = Some(entries);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for PreloadDocumentFinder {
|
||||
type Item = ModuleSpecifier;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
// drain the pending files
|
||||
while let Some(path) = self.pending_files.pop() {
|
||||
if let Some(specifier) = Self::get_valid_specifier(&path) {
|
||||
return Some(specifier);
|
||||
}
|
||||
}
|
||||
|
||||
// then go through the current entries and directories
|
||||
while !self.pending_dirs.is_empty() || self.current_entries.is_some() {
|
||||
match self.read_next_file_entry() {
|
||||
Some(entry) => return Some(entry),
|
||||
None => {
|
||||
self.queue_next_file_entries();
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::npm::NpmResolution;
|
||||
|
||||
use super::*;
|
||||
use import_map::ImportMap;
|
||||
use pretty_assertions::assert_eq;
|
||||
use test_util::TempDir;
|
||||
|
||||
fn setup(temp_dir: &TempDir) -> (Documents, PathBuf) {
|
||||
|
@ -1616,6 +1783,7 @@ console.log(b, "hello deno");
|
|||
.unwrap();
|
||||
|
||||
documents.update_config(
|
||||
vec![],
|
||||
Some(Arc::new(import_map)),
|
||||
None,
|
||||
None,
|
||||
|
@ -1655,6 +1823,7 @@ console.log(b, "hello deno");
|
|||
.unwrap();
|
||||
|
||||
documents.update_config(
|
||||
vec![],
|
||||
Some(Arc::new(import_map)),
|
||||
None,
|
||||
None,
|
||||
|
@ -1676,4 +1845,64 @@ console.log(b, "hello deno");
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_pre_load_document_finder() {
|
||||
let temp_dir = TempDir::new();
|
||||
temp_dir.create_dir_all("root1/node_modules/");
|
||||
temp_dir.write("root1/node_modules/mod.ts", ""); // no, node_modules
|
||||
|
||||
temp_dir.create_dir_all("root1/sub_dir");
|
||||
temp_dir.create_dir_all("root1/.git");
|
||||
temp_dir.create_dir_all("root1/file.ts"); // no, directory
|
||||
temp_dir.write("root1/mod1.ts", ""); // yes
|
||||
temp_dir.write("root1/mod2.js", ""); // yes
|
||||
temp_dir.write("root1/mod3.tsx", ""); // yes
|
||||
temp_dir.write("root1/mod4.d.ts", ""); // yes
|
||||
temp_dir.write("root1/mod5.jsx", ""); // yes
|
||||
temp_dir.write("root1/mod6.mjs", ""); // yes
|
||||
temp_dir.write("root1/mod7.mts", ""); // yes
|
||||
temp_dir.write("root1/mod8.d.mts", ""); // yes
|
||||
temp_dir.write("root1/other.json", ""); // no, json
|
||||
temp_dir.write("root1/other.txt", ""); // no, text file
|
||||
temp_dir.write("root1/other.wasm", ""); // no, don't load wasm
|
||||
temp_dir.write("root1/sub_dir/mod.ts", ""); // yes
|
||||
temp_dir.write("root1/sub_dir/data.min.ts", ""); // no, minified file
|
||||
temp_dir.write("root1/.git/main.ts", ""); // no, .git folder
|
||||
|
||||
temp_dir.create_dir_all("root2/folder");
|
||||
temp_dir.write("root2/file1.ts", ""); // yes, provided
|
||||
temp_dir.write("root2/file2.ts", ""); // no, not provided
|
||||
temp_dir.write("root2/folder/main.ts", ""); // yes, provided
|
||||
|
||||
temp_dir.create_dir_all("root3/");
|
||||
temp_dir.write("root3/mod.ts", ""); // no, not provided
|
||||
|
||||
let mut urls = PreloadDocumentFinder::from_root_urls(&vec![
|
||||
temp_dir.uri().join("root1/").unwrap(),
|
||||
temp_dir.uri().join("root2/file1.ts").unwrap(),
|
||||
temp_dir.uri().join("root2/folder/").unwrap(),
|
||||
])
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// order doesn't matter
|
||||
urls.sort();
|
||||
|
||||
assert_eq!(
|
||||
urls,
|
||||
vec![
|
||||
temp_dir.uri().join("root1/mod1.ts").unwrap(),
|
||||
temp_dir.uri().join("root1/mod2.js").unwrap(),
|
||||
temp_dir.uri().join("root1/mod3.tsx").unwrap(),
|
||||
temp_dir.uri().join("root1/mod4.d.ts").unwrap(),
|
||||
temp_dir.uri().join("root1/mod5.jsx").unwrap(),
|
||||
temp_dir.uri().join("root1/mod6.mjs").unwrap(),
|
||||
temp_dir.uri().join("root1/mod7.mts").unwrap(),
|
||||
temp_dir.uri().join("root1/mod8.d.mts").unwrap(),
|
||||
temp_dir.uri().join("root1/sub_dir/mod.ts").unwrap(),
|
||||
temp_dir.uri().join("root2/file1.ts").unwrap(),
|
||||
temp_dir.uri().join("root2/folder/main.ts").unwrap(),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1138,6 +1138,7 @@ impl Inner {
|
|||
|
||||
fn refresh_documents_config(&mut self) {
|
||||
self.documents.update_config(
|
||||
self.config.enabled_root_urls(),
|
||||
self.maybe_import_map.clone(),
|
||||
self.maybe_config_file.as_ref(),
|
||||
self.maybe_package_json.as_ref(),
|
||||
|
|
|
@ -2803,9 +2803,9 @@ fn op_respond(state: &mut OpState, args: Response) -> bool {
|
|||
fn op_script_names(state: &mut OpState) -> Vec<String> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
let documents = &state.state_snapshot.documents;
|
||||
let open_docs = documents.documents(DocumentsFilter::OpenDiagnosable);
|
||||
let mut result = Vec::new();
|
||||
let all_docs = documents.documents(DocumentsFilter::AllDiagnosable);
|
||||
let mut seen = HashSet::new();
|
||||
let mut result = Vec::new();
|
||||
|
||||
if documents.has_injected_types_node_package() {
|
||||
// ensure this is first so it resolves the node types first
|
||||
|
@ -2822,23 +2822,17 @@ fn op_script_names(state: &mut OpState) -> Vec<String> {
|
|||
}
|
||||
|
||||
// finally include the documents and all their dependencies
|
||||
for doc in &open_docs {
|
||||
let specifier = doc.specifier();
|
||||
if seen.insert(specifier.as_str()) {
|
||||
result.push(specifier.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
// and then all their dependencies (do this after to avoid exists calls)
|
||||
for doc in &open_docs {
|
||||
for dep in doc.dependencies().values() {
|
||||
if let Some(specifier) = dep.get_type().or_else(|| dep.get_code()) {
|
||||
if seen.insert(specifier.as_str()) {
|
||||
// only include dependencies we know to exist otherwise typescript will error
|
||||
if documents.exists(specifier) {
|
||||
result.push(specifier.to_string());
|
||||
}
|
||||
}
|
||||
for doc in &all_docs {
|
||||
let specifiers = std::iter::once(doc.specifier()).chain(
|
||||
doc
|
||||
.dependencies()
|
||||
.values()
|
||||
.filter_map(|dep| dep.get_type().or_else(|| dep.get_code())),
|
||||
);
|
||||
for specifier in specifiers {
|
||||
if seen.insert(specifier.as_str()) && documents.exists(specifier) {
|
||||
// only include dependencies we know to exist otherwise typescript will error
|
||||
result.push(specifier.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,21 +11,21 @@ use std::fs;
|
|||
use std::process::Stdio;
|
||||
use test_util::deno_cmd_with_deno_dir;
|
||||
use test_util::env_vars_for_npm_tests;
|
||||
use test_util::lsp::LspClientBuilder;
|
||||
use test_util::testdata_path;
|
||||
use test_util::TestContextBuilder;
|
||||
use tower_lsp::lsp_types as lsp;
|
||||
|
||||
#[test]
|
||||
fn lsp_startup_shutdown() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.shutdown();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lsp_init_tsconfig() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
|
||||
temp_dir.write(
|
||||
|
@ -58,7 +58,7 @@ fn lsp_init_tsconfig() {
|
|||
|
||||
#[test]
|
||||
fn lsp_tsconfig_types() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
|
||||
temp_dir.write(
|
||||
|
@ -98,7 +98,8 @@ fn lsp_tsconfig_types() {
|
|||
|
||||
#[test]
|
||||
fn lsp_tsconfig_bad_config_path() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize(|builder| {
|
||||
builder
|
||||
.set_config("bad_tsconfig.json")
|
||||
|
@ -123,7 +124,7 @@ fn lsp_tsconfig_bad_config_path() {
|
|||
|
||||
#[test]
|
||||
fn lsp_triple_slash_types() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
let a_dts = "// deno-lint-ignore-file no-var\ndeclare var a: string;";
|
||||
temp_dir.write("a.d.ts", a_dts);
|
||||
|
@ -146,7 +147,7 @@ fn lsp_triple_slash_types() {
|
|||
|
||||
#[test]
|
||||
fn lsp_import_map() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
let import_map = r#"{
|
||||
"imports": {
|
||||
|
@ -205,7 +206,7 @@ fn lsp_import_map() {
|
|||
|
||||
#[test]
|
||||
fn lsp_import_map_data_url() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize(|builder| {
|
||||
builder.set_import_map("data:application/json;utf8,{\"imports\": { \"example\": \"https://deno.land/x/example/mod.ts\" }}");
|
||||
|
@ -230,7 +231,7 @@ fn lsp_import_map_data_url() {
|
|||
|
||||
#[test]
|
||||
fn lsp_import_map_config_file() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
temp_dir.write(
|
||||
"deno.import_map.jsonc",
|
||||
|
@ -297,7 +298,7 @@ fn lsp_import_map_config_file() {
|
|||
|
||||
#[test]
|
||||
fn lsp_import_map_embedded_in_config_file() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
temp_dir.write(
|
||||
"deno.embedded_import_map.jsonc",
|
||||
|
@ -358,7 +359,7 @@ fn lsp_import_map_embedded_in_config_file() {
|
|||
|
||||
#[test]
|
||||
fn lsp_deno_task() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
temp_dir.write(
|
||||
"deno.jsonc",
|
||||
|
@ -393,7 +394,7 @@ fn lsp_deno_task() {
|
|||
|
||||
#[test]
|
||||
fn lsp_import_assertions() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize(|builder| {
|
||||
builder.set_import_map("data:application/json;utf8,{\"imports\": { \"example\": \"https://deno.land/x/example/mod.ts\" }}");
|
||||
|
@ -509,7 +510,7 @@ fn lsp_import_assertions() {
|
|||
|
||||
#[test]
|
||||
fn lsp_import_map_import_completions() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
temp_dir.write(
|
||||
"import-map.json",
|
||||
|
@ -649,7 +650,8 @@ fn lsp_import_map_import_completions() {
|
|||
|
||||
#[test]
|
||||
fn lsp_hover() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -690,7 +692,8 @@ fn lsp_hover() {
|
|||
|
||||
#[test]
|
||||
fn lsp_hover_asset() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -747,7 +750,7 @@ fn lsp_hover_asset() {
|
|||
|
||||
#[test]
|
||||
fn lsp_hover_disabled() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize(|builder| {
|
||||
builder.set_deno_enable(false);
|
||||
|
@ -779,7 +782,7 @@ fn lsp_hover_disabled() {
|
|||
|
||||
#[test]
|
||||
fn lsp_inlay_hints() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize(|builder| {
|
||||
builder.enable_inlay_hints();
|
||||
|
@ -882,7 +885,8 @@ fn lsp_inlay_hints() {
|
|||
|
||||
#[test]
|
||||
fn lsp_inlay_hints_not_enabled() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -929,11 +933,11 @@ fn lsp_inlay_hints_not_enabled() {
|
|||
#[test]
|
||||
fn lsp_workspace_enable_paths() {
|
||||
fn run_test(use_trailing_slash: bool) {
|
||||
let context = TestContextBuilder::new().build();
|
||||
// we aren't actually writing anything to the tempdir in this test, but we
|
||||
// just need a legitimate file path on the host system so that logic that
|
||||
// tries to convert to and from the fs paths works on all env
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
temp_dir.create_dir_all("worker");
|
||||
temp_dir.write("worker/shared.ts", "export const a = 1");
|
||||
temp_dir.write("worker/other.ts", "import { a } from './shared.ts';\na;");
|
||||
|
||||
let root_specifier = temp_dir.uri();
|
||||
|
||||
|
@ -985,7 +989,11 @@ fn lsp_workspace_enable_paths() {
|
|||
"uri": root_specifier.join("./worker/file.ts").unwrap(),
|
||||
"languageId": "typescript",
|
||||
"version": 1,
|
||||
"text": "console.log(Date.now());\n"
|
||||
"text": concat!(
|
||||
"console.log(Date.now());\n",
|
||||
"import { a } from './shared.ts';\n",
|
||||
"a;\n",
|
||||
),
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -1072,6 +1080,56 @@ fn lsp_workspace_enable_paths() {
|
|||
})
|
||||
);
|
||||
|
||||
// check that the file system documents were auto-discovered
|
||||
// via the enabled paths
|
||||
let res = client.write_request(
|
||||
"textDocument/references",
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": root_specifier.join("./worker/file.ts").unwrap(),
|
||||
},
|
||||
"position": { "line": 2, "character": 0 },
|
||||
"context": {
|
||||
"includeDeclaration": true
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
res,
|
||||
json!([{
|
||||
"uri": root_specifier.join("./worker/file.ts").unwrap(),
|
||||
"range": {
|
||||
"start": { "line": 1, "character": 9 },
|
||||
"end": { "line": 1, "character": 10 }
|
||||
}
|
||||
}, {
|
||||
"uri": root_specifier.join("./worker/file.ts").unwrap(),
|
||||
"range": {
|
||||
"start": { "line": 2, "character": 0 },
|
||||
"end": { "line": 2, "character": 1 }
|
||||
}
|
||||
}, {
|
||||
"uri": root_specifier.join("./worker/shared.ts").unwrap(),
|
||||
"range": {
|
||||
"start": { "line": 0, "character": 13 },
|
||||
"end": { "line": 0, "character": 14 }
|
||||
}
|
||||
}, {
|
||||
"uri": root_specifier.join("./worker/other.ts").unwrap(),
|
||||
"range": {
|
||||
"start": { "line": 0, "character": 9 },
|
||||
"end": { "line": 0, "character": 10 }
|
||||
}
|
||||
}, {
|
||||
"uri": root_specifier.join("./worker/other.ts").unwrap(),
|
||||
"range": {
|
||||
"start": { "line": 1, "character": 0 },
|
||||
"end": { "line": 1, "character": 1 }
|
||||
}
|
||||
}])
|
||||
);
|
||||
|
||||
client.shutdown();
|
||||
}
|
||||
|
||||
|
@ -1081,7 +1139,8 @@ fn lsp_workspace_enable_paths() {
|
|||
|
||||
#[test]
|
||||
fn lsp_hover_unstable_disabled() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -1120,7 +1179,8 @@ fn lsp_hover_unstable_disabled() {
|
|||
|
||||
#[test]
|
||||
fn lsp_hover_unstable_enabled() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize(|builder| {
|
||||
builder.set_unstable(true);
|
||||
});
|
||||
|
@ -1163,7 +1223,8 @@ fn lsp_hover_unstable_enabled() {
|
|||
|
||||
#[test]
|
||||
fn lsp_hover_change_mbc() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
json!({
|
||||
|
@ -1228,7 +1289,7 @@ fn lsp_hover_change_mbc() {
|
|||
|
||||
#[test]
|
||||
fn lsp_hover_closed_document() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
temp_dir.write("a.ts", r#"export const a = "a";"#);
|
||||
temp_dir.write("b.ts", r#"export * from "./a.ts";"#);
|
||||
|
@ -1320,7 +1381,10 @@ fn lsp_hover_closed_document() {
|
|||
|
||||
#[test]
|
||||
fn lsp_hover_dependency() {
|
||||
let context = TestContextBuilder::new().use_http_server().build();
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
|
@ -1466,7 +1530,8 @@ fn lsp_hover_dependency() {
|
|||
// unable to resolve dependencies when there was an invalid syntax in the module
|
||||
#[test]
|
||||
fn lsp_hover_deps_preserved_when_invalid_parse() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -1557,7 +1622,10 @@ fn lsp_hover_deps_preserved_when_invalid_parse() {
|
|||
|
||||
#[test]
|
||||
fn lsp_hover_typescript_types() {
|
||||
let context = TestContextBuilder::new().use_http_server().build();
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
|
@ -1610,7 +1678,8 @@ fn lsp_hover_typescript_types() {
|
|||
|
||||
#[test]
|
||||
fn lsp_hover_jsdoc_symbol_link() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -1660,7 +1729,8 @@ fn lsp_hover_jsdoc_symbol_link() {
|
|||
|
||||
#[test]
|
||||
fn lsp_goto_type_definition() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
json!({
|
||||
|
@ -1702,7 +1772,8 @@ fn lsp_goto_type_definition() {
|
|||
|
||||
#[test]
|
||||
fn lsp_call_hierarchy() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
json!({
|
||||
|
@ -1831,7 +1902,8 @@ fn lsp_call_hierarchy() {
|
|||
|
||||
#[test]
|
||||
fn lsp_large_doc_changes() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
let large_file_text =
|
||||
fs::read_to_string(testdata_path().join("lsp").join("large_file.txt"))
|
||||
|
@ -1932,7 +2004,8 @@ fn lsp_large_doc_changes() {
|
|||
|
||||
#[test]
|
||||
fn lsp_document_symbol() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
json!({
|
||||
|
@ -2131,7 +2204,8 @@ fn lsp_document_symbol() {
|
|||
|
||||
#[test]
|
||||
fn lsp_folding_range() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
json!({
|
||||
|
@ -2177,7 +2251,8 @@ fn lsp_folding_range() {
|
|||
|
||||
#[test]
|
||||
fn lsp_rename() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
json!({
|
||||
|
@ -2229,7 +2304,8 @@ fn lsp_rename() {
|
|||
|
||||
#[test]
|
||||
fn lsp_selection_range() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
json!({
|
||||
|
@ -2306,7 +2382,8 @@ fn lsp_selection_range() {
|
|||
|
||||
#[test]
|
||||
fn lsp_semantic_tokens() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
json!({
|
||||
|
@ -2365,7 +2442,8 @@ fn lsp_semantic_tokens() {
|
|||
|
||||
#[test]
|
||||
fn lsp_code_lens() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -2539,7 +2617,8 @@ fn lsp_code_lens() {
|
|||
|
||||
#[test]
|
||||
fn lsp_code_lens_impl() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
json!({
|
||||
|
@ -2685,7 +2764,8 @@ fn lsp_code_lens_impl() {
|
|||
|
||||
#[test]
|
||||
fn lsp_code_lens_test() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize(|builder| {
|
||||
builder.disable_testing_api().set_code_lens(None);
|
||||
});
|
||||
|
@ -2940,7 +3020,8 @@ fn lsp_code_lens_test() {
|
|||
|
||||
#[test]
|
||||
fn lsp_code_lens_test_disabled() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize(|builder| {
|
||||
builder.disable_testing_api().set_code_lens(Some(json!({
|
||||
"implementations": true,
|
||||
|
@ -2980,7 +3061,8 @@ fn lsp_code_lens_test_disabled() {
|
|||
|
||||
#[test]
|
||||
fn lsp_code_lens_non_doc_nav_tree() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -3037,7 +3119,8 @@ fn lsp_code_lens_non_doc_nav_tree() {
|
|||
|
||||
#[test]
|
||||
fn lsp_nav_tree_updates() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
json!({
|
||||
|
@ -3177,7 +3260,8 @@ fn lsp_nav_tree_updates() {
|
|||
|
||||
#[test]
|
||||
fn lsp_find_references() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -3285,7 +3369,8 @@ fn lsp_find_references() {
|
|||
|
||||
#[test]
|
||||
fn lsp_signature_help() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
json!({
|
||||
|
@ -3405,7 +3490,8 @@ fn lsp_signature_help() {
|
|||
|
||||
#[test]
|
||||
fn lsp_code_actions() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
json!({
|
||||
|
@ -3592,7 +3678,8 @@ fn lsp_code_actions() {
|
|||
|
||||
#[test]
|
||||
fn lsp_code_actions_deno_cache() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
let diagnostics = client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -3681,7 +3768,8 @@ fn lsp_code_actions_deno_cache() {
|
|||
|
||||
#[test]
|
||||
fn lsp_code_actions_deno_cache_npm() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
let diagnostics = client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -3765,7 +3853,8 @@ fn lsp_code_actions_deno_cache_npm() {
|
|||
|
||||
#[test]
|
||||
fn lsp_code_actions_imports() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -4005,7 +4094,8 @@ export class DuckConfig {
|
|||
|
||||
#[test]
|
||||
fn lsp_code_actions_refactor() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -4214,7 +4304,8 @@ fn lsp_code_actions_refactor() {
|
|||
|
||||
#[test]
|
||||
fn lsp_code_actions_refactor_no_disabled_support() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize(|builder| {
|
||||
builder.with_capabilities(|c| {
|
||||
let doc = c.text_document.as_mut().unwrap();
|
||||
|
@ -4283,7 +4374,8 @@ fn lsp_code_actions_refactor_no_disabled_support() {
|
|||
|
||||
#[test]
|
||||
fn lsp_code_actions_deadlock() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
let large_file_text =
|
||||
fs::read_to_string(testdata_path().join("lsp").join("large_file.txt"))
|
||||
|
@ -4406,7 +4498,8 @@ fn lsp_code_actions_deadlock() {
|
|||
|
||||
#[test]
|
||||
fn lsp_completions() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -4464,7 +4557,8 @@ fn lsp_completions() {
|
|||
|
||||
#[test]
|
||||
fn lsp_completions_private_fields() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -4488,7 +4582,8 @@ fn lsp_completions_private_fields() {
|
|||
|
||||
#[test]
|
||||
fn lsp_completions_optional() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
json!({
|
||||
|
@ -4570,7 +4665,8 @@ fn lsp_completions_optional() {
|
|||
|
||||
#[test]
|
||||
fn lsp_completions_auto_import() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -4654,7 +4750,8 @@ fn lsp_completions_auto_import() {
|
|||
|
||||
#[test]
|
||||
fn lsp_completions_snippet() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
json!({
|
||||
|
@ -4748,7 +4845,8 @@ fn lsp_completions_snippet() {
|
|||
|
||||
#[test]
|
||||
fn lsp_completions_no_snippet() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize(|builder| {
|
||||
builder.with_capabilities(|c| {
|
||||
let doc = c.text_document.as_mut().unwrap();
|
||||
|
@ -4802,7 +4900,10 @@ fn lsp_completions_no_snippet() {
|
|||
|
||||
#[test]
|
||||
fn lsp_completions_npm() {
|
||||
let context = TestContextBuilder::new().use_http_server().build();
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
|
@ -4938,7 +5039,10 @@ fn lsp_completions_npm() {
|
|||
|
||||
#[test]
|
||||
fn lsp_npm_specifier_unopened_file() {
|
||||
let context = TestContextBuilder::new().use_http_server().build();
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
|
||||
|
@ -5017,7 +5121,10 @@ fn lsp_npm_specifier_unopened_file() {
|
|||
|
||||
#[test]
|
||||
fn lsp_completions_node_specifier() {
|
||||
let context = TestContextBuilder::new().use_http_server().build();
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
let diagnostics = client.did_open(json!({
|
||||
|
@ -5238,7 +5345,10 @@ fn lsp_completions_node_specifier() {
|
|||
|
||||
#[test]
|
||||
fn lsp_completions_registry() {
|
||||
let context = TestContextBuilder::new().use_http_server().build();
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize(|builder| {
|
||||
builder.add_test_server_suggestions();
|
||||
|
@ -5301,7 +5411,10 @@ fn lsp_completions_registry() {
|
|||
|
||||
#[test]
|
||||
fn lsp_completions_registry_empty() {
|
||||
let context = TestContextBuilder::new().use_http_server().build();
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize(|builder| {
|
||||
builder.add_test_server_suggestions();
|
||||
|
@ -5361,7 +5474,10 @@ fn lsp_completions_registry_empty() {
|
|||
|
||||
#[test]
|
||||
fn lsp_auto_discover_registry() {
|
||||
let context = TestContextBuilder::new().use_http_server().build();
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
|
@ -5394,7 +5510,10 @@ fn lsp_auto_discover_registry() {
|
|||
|
||||
#[test]
|
||||
fn lsp_cache_location() {
|
||||
let context = TestContextBuilder::new().use_http_server().build();
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let temp_dir = context.temp_dir();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize(|builder| {
|
||||
|
@ -5483,7 +5602,10 @@ fn lsp_cache_location() {
|
|||
/// and cache files.
|
||||
#[test]
|
||||
fn lsp_tls_cert() {
|
||||
let context = TestContextBuilder::new().use_http_server().build();
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize(|builder| {
|
||||
builder
|
||||
|
@ -5570,7 +5692,10 @@ fn lsp_tls_cert() {
|
|||
|
||||
#[test]
|
||||
fn lsp_diagnostics_warn_redirect() {
|
||||
let context = TestContextBuilder::new().use_http_server().build();
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
|
@ -5646,7 +5771,10 @@ fn lsp_diagnostics_warn_redirect() {
|
|||
|
||||
#[test]
|
||||
fn lsp_redirect_quick_fix() {
|
||||
let context = TestContextBuilder::new().use_http_server().build();
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(
|
||||
|
@ -5730,7 +5858,8 @@ fn lsp_redirect_quick_fix() {
|
|||
|
||||
#[test]
|
||||
fn lsp_diagnostics_deprecated() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
let diagnostics = client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -5776,7 +5905,8 @@ fn lsp_diagnostics_deprecated() {
|
|||
|
||||
#[test]
|
||||
fn lsp_diagnostics_deno_types() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
let diagnostics = client
|
||||
.did_open(json!({
|
||||
|
@ -5803,7 +5933,8 @@ fn lsp_diagnostics_deno_types() {
|
|||
|
||||
#[test]
|
||||
fn lsp_diagnostics_refresh_dependents() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -5891,7 +6022,8 @@ struct PerformanceAverages {
|
|||
|
||||
#[test]
|
||||
fn lsp_performance() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -5943,7 +6075,8 @@ fn lsp_performance() {
|
|||
|
||||
#[test]
|
||||
fn lsp_format_no_changes() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -5972,7 +6105,8 @@ fn lsp_format_no_changes() {
|
|||
|
||||
#[test]
|
||||
fn lsp_format_error() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -6000,7 +6134,8 @@ fn lsp_format_error() {
|
|||
|
||||
#[test]
|
||||
fn lsp_format_mbc() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -6055,7 +6190,7 @@ fn lsp_format_mbc() {
|
|||
|
||||
#[test]
|
||||
fn lsp_format_exclude_with_config() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
|
||||
temp_dir.write(
|
||||
|
@ -6108,7 +6243,7 @@ fn lsp_format_exclude_with_config() {
|
|||
|
||||
#[test]
|
||||
fn lsp_format_exclude_default_config() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
|
||||
temp_dir.write(
|
||||
|
@ -6161,7 +6296,8 @@ fn lsp_format_exclude_default_config() {
|
|||
|
||||
#[test]
|
||||
fn lsp_format_json() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -6216,7 +6352,8 @@ fn lsp_format_json() {
|
|||
|
||||
#[test]
|
||||
fn lsp_json_no_diagnostics() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -6253,7 +6390,8 @@ fn lsp_json_no_diagnostics() {
|
|||
|
||||
#[test]
|
||||
fn lsp_format_markdown() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -6300,7 +6438,7 @@ fn lsp_format_markdown() {
|
|||
|
||||
#[test]
|
||||
fn lsp_format_with_config() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
temp_dir.write(
|
||||
"deno.fmt.jsonc",
|
||||
|
@ -6407,7 +6545,8 @@ fn lsp_format_with_config() {
|
|||
|
||||
#[test]
|
||||
fn lsp_markdown_no_diagnostics() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -6444,7 +6583,10 @@ fn lsp_markdown_no_diagnostics() {
|
|||
|
||||
#[test]
|
||||
fn lsp_configuration_did_change() {
|
||||
let context = TestContextBuilder::new().use_http_server().build();
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
|
@ -6537,7 +6679,8 @@ fn lsp_configuration_did_change() {
|
|||
|
||||
#[test]
|
||||
fn lsp_workspace_symbol() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -6631,7 +6774,8 @@ fn lsp_workspace_symbol() {
|
|||
|
||||
#[test]
|
||||
fn lsp_code_actions_ignore_lint() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -6754,7 +6898,8 @@ fn lsp_code_actions_ignore_lint() {
|
|||
/// This test exercises updating an existing deno-lint-ignore-file comment.
|
||||
#[test]
|
||||
fn lsp_code_actions_update_ignore_lint() {
|
||||
let mut client = LspClientBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
|
@ -6879,7 +7024,7 @@ console.log(snake_case);
|
|||
|
||||
#[test]
|
||||
fn lsp_lint_with_config() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
|
||||
temp_dir.write(
|
||||
|
@ -6920,7 +7065,7 @@ fn lsp_lint_with_config() {
|
|||
|
||||
#[test]
|
||||
fn lsp_lint_exclude_with_config() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
|
||||
temp_dir.write(
|
||||
|
@ -6961,7 +7106,10 @@ fn lsp_lint_exclude_with_config() {
|
|||
|
||||
#[test]
|
||||
fn lsp_jsx_import_source_pragma() {
|
||||
let context = TestContextBuilder::new().use_http_server().build();
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
|
@ -7058,7 +7206,7 @@ struct TestRunResponseParams {
|
|||
|
||||
#[test]
|
||||
fn lsp_testing_api() {
|
||||
let context = TestContextBuilder::new().build();
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
|
||||
let contents = r#"
|
||||
|
@ -7216,3 +7364,56 @@ Deno.test({
|
|||
|
||||
client.shutdown();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lsp_closed_file_find_references() {
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
temp_dir.write("./mod.ts", "export const a = 5;");
|
||||
temp_dir.write(
|
||||
"./mod.test.ts",
|
||||
"import { a } from './mod.ts'; console.log(a);",
|
||||
);
|
||||
let temp_dir_url = temp_dir.uri();
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
"uri": temp_dir_url.join("mod.ts").unwrap(),
|
||||
"languageId": "typescript",
|
||||
"version": 1,
|
||||
"text": r#"export const a = 5;"#
|
||||
}
|
||||
}));
|
||||
let res = client.write_request(
|
||||
"textDocument/references",
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": temp_dir_url.join("mod.ts").unwrap(),
|
||||
},
|
||||
"position": { "line": 0, "character": 13 },
|
||||
"context": {
|
||||
"includeDeclaration": false
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
res,
|
||||
json!([{
|
||||
"uri": temp_dir_url.join("mod.test.ts").unwrap(),
|
||||
"range": {
|
||||
"start": { "line": 0, "character": 9 },
|
||||
"end": { "line": 0, "character": 10 }
|
||||
}
|
||||
}, {
|
||||
"uri": temp_dir_url.join("mod.test.ts").unwrap(),
|
||||
"range": {
|
||||
"start": { "line": 0, "character": 42 },
|
||||
"end": { "line": 0, "character": 43 }
|
||||
}
|
||||
}])
|
||||
);
|
||||
|
||||
client.shutdown();
|
||||
}
|
||||
|
|
|
@ -131,24 +131,43 @@ fn pty_complete_expression() {
|
|||
|
||||
#[test]
|
||||
fn pty_complete_imports() {
|
||||
util::with_pty(&["repl", "-A"], |mut console| {
|
||||
// single quotes
|
||||
console.write_line_raw("import './run/001_hel\t'");
|
||||
console.expect("Hello World");
|
||||
// double quotes
|
||||
console.write_line_raw("import { output } from \"./run/045_out\t\"");
|
||||
console.expect("\"./run/045_output.ts\"");
|
||||
console.write_line_raw("output('testing output');");
|
||||
console.expect("testing output");
|
||||
});
|
||||
let context = TestContextBuilder::default().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
temp_dir.create_dir_all("subdir");
|
||||
temp_dir.write("./subdir/my_file.ts", "");
|
||||
temp_dir.create_dir_all("run");
|
||||
temp_dir.write("./run/hello.ts", "console.log('Hello World');");
|
||||
temp_dir.write(
|
||||
"./run/output.ts",
|
||||
r#"export function output(text: string) {
|
||||
console.log(text);
|
||||
}
|
||||
"#,
|
||||
);
|
||||
context
|
||||
.new_command()
|
||||
.args_vec(["repl", "-A"])
|
||||
.with_pty(|mut console| {
|
||||
// single quotes
|
||||
console.write_line_raw("import './run/hel\t'");
|
||||
console.expect("Hello World");
|
||||
// double quotes
|
||||
console.write_line_raw("import { output } from \"./run/out\t\"");
|
||||
console.expect("\"./run/output.ts\"");
|
||||
console.write_line_raw("output('testing output');");
|
||||
console.expect("testing output");
|
||||
});
|
||||
|
||||
// ensure when the directory changes that the suggestions come from the cwd
|
||||
util::with_pty(&["repl", "-A"], |mut console| {
|
||||
console.write_line("Deno.chdir('./subdir');");
|
||||
console.expect("undefined");
|
||||
console.write_line_raw("import '../run/001_hel\t'");
|
||||
console.expect("Hello World");
|
||||
});
|
||||
context
|
||||
.new_command()
|
||||
.args_vec(["repl", "-A"])
|
||||
.with_pty(|mut console| {
|
||||
console.write_line("Deno.chdir('./subdir');");
|
||||
console.expect("undefined");
|
||||
console.write_line_raw("import '../run/he\t'");
|
||||
console.expect("Hello World");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -283,10 +302,15 @@ fn let_redeclaration() {
|
|||
|
||||
#[test]
|
||||
fn repl_cwd() {
|
||||
util::with_pty(&["repl", "-A"], |mut console| {
|
||||
console.write_line("Deno.cwd()");
|
||||
console.expect("testdata");
|
||||
});
|
||||
let context = TestContextBuilder::default().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
context
|
||||
.new_command()
|
||||
.args_vec(["repl", "-A"])
|
||||
.with_pty(|mut console| {
|
||||
console.write_line("Deno.cwd()");
|
||||
console.expect(temp_dir.path().file_name().unwrap().to_str().unwrap());
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -384,18 +408,30 @@ fn multiline() {
|
|||
|
||||
#[test]
|
||||
fn import() {
|
||||
util::with_pty(&["repl", "-A"], |mut console| {
|
||||
console.write_line("import('./subdir/auto_print_hello.ts')");
|
||||
console.expect("hello!");
|
||||
});
|
||||
let context = TestContextBuilder::default()
|
||||
.use_copy_temp_dir("./subdir")
|
||||
.build();
|
||||
context
|
||||
.new_command()
|
||||
.args_vec(["repl", "-A"])
|
||||
.with_pty(|mut console| {
|
||||
console.write_line("import('./subdir/auto_print_hello.ts')");
|
||||
console.expect("hello!");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import_declarations() {
|
||||
util::with_pty(&["repl", "-A"], |mut console| {
|
||||
console.write_line("import './subdir/auto_print_hello.ts'");
|
||||
console.expect("hello!");
|
||||
});
|
||||
let context = TestContextBuilder::default()
|
||||
.use_copy_temp_dir("./subdir")
|
||||
.build();
|
||||
context
|
||||
.new_command()
|
||||
.args_vec(["repl", "-A"])
|
||||
.with_pty(|mut console| {
|
||||
console.write_line("import './subdir/auto_print_hello.ts'");
|
||||
console.expect("hello!");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -14,6 +14,7 @@ use trust_dns_client::serialize::txt::Lexer;
|
|||
use trust_dns_client::serialize::txt::Parser;
|
||||
use util::assert_contains;
|
||||
use util::env_vars_for_npm_tests_no_sync_download;
|
||||
use util::TestContext;
|
||||
use util::TestContextBuilder;
|
||||
|
||||
itest!(stdout_write_all {
|
||||
|
@ -571,9 +572,10 @@ itest!(_089_run_allow_list {
|
|||
|
||||
#[test]
|
||||
fn _090_run_permissions_request() {
|
||||
util::with_pty(
|
||||
&["run", "--quiet", "run/090_run_permissions_request.ts"],
|
||||
|mut console| {
|
||||
TestContext::default()
|
||||
.new_command()
|
||||
.args_vec(["run", "--quiet", "run/090_run_permissions_request.ts"])
|
||||
.with_pty(|mut console| {
|
||||
console.expect(concat!(
|
||||
"┌ ⚠️ Deno requests run access to \"ls\".\r\n",
|
||||
"├ Requested by `Deno.permissions.query()` API.\r\n",
|
||||
|
@ -592,15 +594,15 @@ fn _090_run_permissions_request() {
|
|||
console.expect("Denied run access to \"cat\".");
|
||||
console.expect("granted");
|
||||
console.expect("denied");
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn _090_run_permissions_request_sync() {
|
||||
util::with_pty(
|
||||
&["run", "--quiet", "run/090_run_permissions_request_sync.ts"],
|
||||
|mut console| {
|
||||
TestContext::default()
|
||||
.new_command()
|
||||
.args_vec(["run", "--quiet", "run/090_run_permissions_request_sync.ts"])
|
||||
.with_pty(|mut console| {
|
||||
console.expect(concat!(
|
||||
"┌ ⚠️ Deno requests run access to \"ls\".\r\n",
|
||||
"├ Requested by `Deno.permissions.query()` API.\r\n",
|
||||
|
@ -619,15 +621,15 @@ fn _090_run_permissions_request_sync() {
|
|||
console.expect("Denied run access to \"cat\".");
|
||||
console.expect("granted");
|
||||
console.expect("denied");
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn permissions_prompt_allow_all() {
|
||||
util::with_pty(
|
||||
&["run", "--quiet", "run/permissions_prompt_allow_all.ts"],
|
||||
|mut console| {
|
||||
TestContext::default()
|
||||
.new_command()
|
||||
.args_vec(["run", "--quiet", "run/permissions_prompt_allow_all.ts"])
|
||||
.with_pty(|mut console| {
|
||||
// "run" permissions
|
||||
console.expect(concat!(
|
||||
"┌ ⚠️ Deno requests run access to \"FOO\".\r\n",
|
||||
|
@ -697,9 +699,10 @@ fn permissions_prompt_allow_all() {
|
|||
|
||||
#[test]
|
||||
fn permissions_prompt_allow_all_2() {
|
||||
util::with_pty(
|
||||
&["run", "--quiet", "run/permissions_prompt_allow_all_2.ts"],
|
||||
|mut console| {
|
||||
TestContext::default()
|
||||
.new_command()
|
||||
.args_vec(["run", "--quiet", "run/permissions_prompt_allow_all_2.ts"])
|
||||
.with_pty(|mut console| {
|
||||
// "env" permissions
|
||||
console.expect(concat!(
|
||||
"┌ ⚠️ Deno requests env access to \"FOO\".\r\n",
|
||||
|
@ -728,15 +731,15 @@ fn permissions_prompt_allow_all_2() {
|
|||
));
|
||||
console.write_line_raw("A");
|
||||
console.expect("✅ Granted all read access.");
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn permissions_prompt_allow_all_lowercase_a() {
|
||||
util::with_pty(
|
||||
&["run", "--quiet", "run/permissions_prompt_allow_all.ts"],
|
||||
|mut console| {
|
||||
TestContext::default()
|
||||
.new_command()
|
||||
.args_vec(["run", "--quiet", "run/permissions_prompt_allow_all.ts"])
|
||||
.with_pty(|mut console| {
|
||||
// "run" permissions
|
||||
console.expect(concat!(
|
||||
"┌ ⚠️ Deno requests run access to \"FOO\".\r\n",
|
||||
|
@ -746,8 +749,7 @@ fn permissions_prompt_allow_all_lowercase_a() {
|
|||
));
|
||||
console.write_line_raw("a");
|
||||
console.expect("Unrecognized option.");
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
itest!(_091_use_define_for_class_fields {
|
||||
|
@ -2141,6 +2143,7 @@ fn dont_cache_on_check_fail() {
|
|||
|
||||
mod permissions {
|
||||
use test_util as util;
|
||||
use util::TestContext;
|
||||
|
||||
// TODO(bartlomieju): remove --unstable once Deno.Command is stabilized
|
||||
#[test]
|
||||
|
@ -2503,9 +2506,10 @@ mod permissions {
|
|||
|
||||
#[test]
|
||||
fn _061_permissions_request() {
|
||||
util::with_pty(
|
||||
&["run", "--quiet", "run/061_permissions_request.ts"],
|
||||
|mut console| {
|
||||
TestContext::default()
|
||||
.new_command()
|
||||
.args_vec(["run", "--quiet", "run/061_permissions_request.ts"])
|
||||
.with_pty(|mut console| {
|
||||
console.expect(concat!(
|
||||
"┌ ⚠️ Deno requests read access to \"foo\".\r\n",
|
||||
"├ Requested by `Deno.permissions.query()` API.\r\n",
|
||||
|
@ -2523,15 +2527,15 @@ mod permissions {
|
|||
console.expect("granted");
|
||||
console.expect("prompt");
|
||||
console.expect("denied");
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn _061_permissions_request_sync() {
|
||||
util::with_pty(
|
||||
&["run", "--quiet", "run/061_permissions_request_sync.ts"],
|
||||
|mut console| {
|
||||
TestContext::default()
|
||||
.new_command()
|
||||
.args_vec(["run", "--quiet", "run/061_permissions_request_sync.ts"])
|
||||
.with_pty(|mut console| {
|
||||
console.expect(concat!(
|
||||
"┌ ⚠️ Deno requests read access to \"foo\".\r\n",
|
||||
"├ Requested by `Deno.permissions.query()` API.\r\n",
|
||||
|
@ -2549,15 +2553,15 @@ mod permissions {
|
|||
console.expect("granted");
|
||||
console.expect("prompt");
|
||||
console.expect("denied");
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn _062_permissions_request_global() {
|
||||
util::with_pty(
|
||||
&["run", "--quiet", "run/062_permissions_request_global.ts"],
|
||||
|mut console| {
|
||||
TestContext::default()
|
||||
.new_command()
|
||||
.args_vec(["run", "--quiet", "run/062_permissions_request_global.ts"])
|
||||
.with_pty(|mut console| {
|
||||
console.expect(concat!(
|
||||
"┌ ⚠️ Deno requests read access.\r\n",
|
||||
"├ Requested by `Deno.permissions.query()` API.\r\n",
|
||||
|
@ -2571,19 +2575,15 @@ mod permissions {
|
|||
.expect("PermissionStatus { state: \"granted\", onchange: null }");
|
||||
console
|
||||
.expect("PermissionStatus { state: \"granted\", onchange: null }");
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn _062_permissions_request_global_sync() {
|
||||
util::with_pty(
|
||||
&[
|
||||
"run",
|
||||
"--quiet",
|
||||
"run/062_permissions_request_global_sync.ts",
|
||||
],
|
||||
|mut console| {
|
||||
TestContext::default()
|
||||
.new_command()
|
||||
.args_vec(["run", "--quiet", "run/062_permissions_request_global_sync.ts"])
|
||||
.with_pty(|mut console| {
|
||||
console.expect(concat!(
|
||||
"┌ ⚠️ Deno requests read access.\r\n",
|
||||
"├ Requested by `Deno.permissions.query()` API.\r\n",
|
||||
|
@ -2597,8 +2597,7 @@ mod permissions {
|
|||
.expect("PermissionStatus { state: \"granted\", onchange: null }");
|
||||
console
|
||||
.expect("PermissionStatus { state: \"granted\", onchange: null }");
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
itest!(_063_permissions_revoke {
|
||||
|
@ -2623,9 +2622,10 @@ mod permissions {
|
|||
|
||||
#[test]
|
||||
fn _066_prompt() {
|
||||
util::with_pty(
|
||||
&["run", "--quiet", "--unstable", "run/066_prompt.ts"],
|
||||
|mut console| {
|
||||
TestContext::default()
|
||||
.new_command()
|
||||
.args_vec(["run", "--quiet", "--unstable", "run/066_prompt.ts"])
|
||||
.with_pty(|mut console| {
|
||||
console.expect("What is your name? [Jane Doe] ");
|
||||
console.write_line_raw("John Doe");
|
||||
console.expect("Your name is John Doe.");
|
||||
|
@ -2658,8 +2658,7 @@ mod permissions {
|
|||
console.expect("What is EOF? ");
|
||||
console.write_line("");
|
||||
console.expect("Your answer is null");
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
itest!(dynamic_import_permissions_remote_remote {
|
||||
|
@ -2715,28 +2714,31 @@ itest!(byte_order_mark {
|
|||
|
||||
#[test]
|
||||
fn issue9750() {
|
||||
util::with_pty(&["run", "--prompt", "run/issue9750.js"], |mut console| {
|
||||
console.expect("Enter 'yy':");
|
||||
console.write_line_raw("yy");
|
||||
console.expect(concat!(
|
||||
"┌ ⚠️ Deno requests env access.\r\n",
|
||||
"├ Requested by `Deno.permissions.query()` API.\r\n",
|
||||
"├ Run again with --allow-env to bypass this prompt.\r\n",
|
||||
"└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)",
|
||||
));
|
||||
console.write_line_raw("n");
|
||||
console.expect("Denied env access.");
|
||||
console.expect(concat!(
|
||||
"┌ ⚠️ Deno requests env access to \"SECRET\".\r\n",
|
||||
"├ Run again with --allow-env to bypass this prompt.\r\n",
|
||||
"└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)",
|
||||
));
|
||||
console.write_line_raw("n");
|
||||
console.expect_all(&[
|
||||
"Denied env access to \"SECRET\".",
|
||||
"PermissionDenied: Requires env access to \"SECRET\", run again with the --allow-env flag",
|
||||
]);
|
||||
});
|
||||
TestContext::default()
|
||||
.new_command()
|
||||
.args_vec(["run", "--prompt", "run/issue9750.js"])
|
||||
.with_pty(|mut console| {
|
||||
console.expect("Enter 'yy':");
|
||||
console.write_line_raw("yy");
|
||||
console.expect(concat!(
|
||||
"┌ ⚠️ Deno requests env access.\r\n",
|
||||
"├ Requested by `Deno.permissions.query()` API.\r\n",
|
||||
"├ Run again with --allow-env to bypass this prompt.\r\n",
|
||||
"└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)",
|
||||
));
|
||||
console.write_line_raw("n");
|
||||
console.expect("Denied env access.");
|
||||
console.expect(concat!(
|
||||
"┌ ⚠️ Deno requests env access to \"SECRET\".\r\n",
|
||||
"├ Run again with --allow-env to bypass this prompt.\r\n",
|
||||
"└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)",
|
||||
));
|
||||
console.write_line_raw("n");
|
||||
console.expect_all(&[
|
||||
"Denied env access to \"SECRET\".",
|
||||
"PermissionDenied: Requires env access to \"SECRET\", run again with the --allow-env flag",
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
// Regression test for https://github.com/denoland/deno/issues/11451.
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
// These tests are intended to only test integration.
|
||||
|
||||
use test_util::env_vars_for_npm_tests;
|
||||
use test_util::TestContext;
|
||||
|
||||
itest!(task_no_args {
|
||||
args: "task -q --config task/deno_json/deno.json",
|
||||
|
@ -53,12 +54,12 @@ itest!(task_non_existent {
|
|||
#[test]
|
||||
fn task_emoji() {
|
||||
// this bug only appears when using a pty/tty
|
||||
test_util::with_pty(
|
||||
&["task", "--config", "task/deno_json/deno.json", "echo_emoji"],
|
||||
|mut console| {
|
||||
TestContext::default()
|
||||
.new_command()
|
||||
.args_vec(["task", "--config", "task/deno_json/deno.json", "echo_emoji"])
|
||||
.with_pty(|mut console| {
|
||||
console.expect("Task echo_emoji echo 🔥\r\n🔥");
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
itest!(task_boolean_logic {
|
||||
|
|
|
@ -406,10 +406,9 @@ fn file_protocol() {
|
|||
.unwrap()
|
||||
.to_string();
|
||||
|
||||
let context = TestContext::default();
|
||||
context
|
||||
TestContext::default()
|
||||
.new_command()
|
||||
.args_vec(vec!["test".to_string(), file_url])
|
||||
.args_vec(["test", file_url.as_str()])
|
||||
.run()
|
||||
.assert_matches_file("test/file_protocol.out");
|
||||
}
|
||||
|
|
|
@ -228,8 +228,11 @@ impl TestCommandBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn args_vec(&mut self, args: Vec<String>) -> &mut Self {
|
||||
self.args_vec = args;
|
||||
pub fn args_vec<T: AsRef<str>, I: IntoIterator<Item = T>>(
|
||||
&mut self,
|
||||
args: I,
|
||||
) -> &mut Self {
|
||||
self.args_vec = args.into_iter().map(|a| a.as_ref().to_string()).collect();
|
||||
self
|
||||
}
|
||||
|
||||
|
|
|
@ -2093,8 +2093,7 @@ impl<'a> CheckOutputIntegrationTest<'a> {
|
|||
command_builder.args(self.args);
|
||||
}
|
||||
if !self.args_vec.is_empty() {
|
||||
command_builder
|
||||
.args_vec(self.args_vec.iter().map(|a| a.to_string()).collect());
|
||||
command_builder.args_vec(self.args_vec.clone());
|
||||
}
|
||||
if let Some(input) = &self.input {
|
||||
command_builder.stdin(input);
|
||||
|
@ -2167,11 +2166,8 @@ pub fn pattern_match(pattern: &str, s: &str, wildcard: &str) -> bool {
|
|||
}
|
||||
|
||||
pub fn with_pty(deno_args: &[&str], action: impl FnMut(Pty)) {
|
||||
let context = TestContextBuilder::default().build();
|
||||
context
|
||||
.new_command()
|
||||
.args_vec(deno_args.iter().map(ToString::to_string).collect())
|
||||
.with_pty(action);
|
||||
let context = TestContextBuilder::default().use_temp_cwd().build();
|
||||
context.new_command().args_vec(deno_args).with_pty(action);
|
||||
}
|
||||
|
||||
pub struct WrkOutput {
|
||||
|
|
Loading…
Reference in a new issue