use crate::{catalog::Catalog, web::HttpClient, workspace, Backend, LANGUAGE};
use itertools::Itertools;
use log::info;
use std::{collections::HashMap, fs, path::Path};
use tempdir::TempDir;
use tower_lsp::{
lsp_types::{
ClientCapabilities, GeneralClientCapabilities, InitializeParams, InitializedParams,
PositionEncodingKind, WorkspaceFolder,
},
LanguageServer, LspService,
};
use tree_sitter_c2rust::Parser;
pub fn setup() {
}
#[derive(Debug, Clone)]
pub enum WorkspaceMember {
Folder {
name: String,
children: Vec<WorkspaceMember>,
},
CatalogFile(Catalog),
OmnFile {
name: String,
content: String,
},
OwxFile {
name: String,
content: String,
},
}
pub fn arrange_workspace_folders<F>(root_member_generator: F) -> TempDir
where
F: Fn(&Path) -> Vec<WorkspaceMember>,
{
let dir = TempDir::new("owl-ms-test").unwrap();
let root_members = root_member_generator(dir.path());
for member in root_members.clone() {
arrange_workspace_member(member, dir.path());
}
info!("Arranged Workspace Member {:#?}", root_members);
dir
}
fn arrange_workspace_member(member: WorkspaceMember, path: &Path) {
match member {
WorkspaceMember::Folder { name, children } => {
let inner_path = path.join(name);
fs::create_dir(inner_path.clone()).unwrap();
for child in children {
arrange_workspace_member(child, &inner_path);
}
}
WorkspaceMember::CatalogFile(catalog) => {
let content = quick_xml::se::to_string::<Catalog>(&catalog).unwrap();
fs::write(path.join("catalog-v001.xml"), content).unwrap();
}
WorkspaceMember::OmnFile { name, content } => {
fs::write(path.join(name), content).unwrap();
}
WorkspaceMember::OwxFile { name, content } => {
fs::write(path.join(name), content).unwrap();
}
}
}
pub fn arrange_parser() -> Parser {
let mut parser = Parser::new();
parser.set_language(&LANGUAGE).unwrap();
parser
}
pub async fn arrange_init_backend(
service: &LspService<Backend>,
workspacefolder: Option<WorkspaceFolder>,
) {
let result = service
.inner()
.initialize(InitializeParams {
workspace_folders: workspacefolder.map(|w| vec![w]),
capabilities: ClientCapabilities {
general: Some(GeneralClientCapabilities {
position_encodings: Some(vec![PositionEncodingKind::UTF8]),
..Default::default()
}),
..Default::default()
},
..Default::default()
})
.await;
assert!(result.is_ok(), "Initialize returned {:#?}", result);
service.inner().initialized(InitializedParams {}).await;
}
pub async fn arrange_backend(
workspace_folder: Option<WorkspaceFolder>,
data: Vec<(&str, &str)>,
) -> LspService<Backend> {
let http_client = Box::new(StaticClient {
data: [
("http://www.w3.org/1999/02/22-rdf-syntax-ns#", "dummy"),
("http://www.w3.org/2002/07/owl#", "dummy"),
("http://www.w3.org/2000/01/rdf-schema#", "dummy"),
]
.into_iter()
.chain(data.into_iter())
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect(),
});
let (service, _) = LspService::new(|client| Backend::new(client, http_client));
arrange_init_backend(&service, workspace_folder).await;
service
}
#[allow(dead_code)]
pub async fn assert_empty_diagnostics(service: &LspService<Backend>) {
let sync = service.inner().read_sync().await;
let workspaces = sync.workspaces();
for workspace in workspaces.iter() {
for doc in workspace.internal_documents() {
let diagnostics = doc
.diagnostics(workspace)
.into_iter()
.collect_vec();
assert_eq!(diagnostics, vec![], "rope:\n{}", doc.rope());
}
}
}
pub async fn service_diagnostics(service: &LspService<Backend>) -> Vec<workspace::Diagnostic> {
let sync = service.inner().read_sync().await;
let workspaces = sync.workspaces();
workspaces
.iter()
.flat_map(|workspace| {
workspace
.internal_documents()
.flat_map(|doc| doc.diagnostics(workspace))
})
.collect_vec()
}
#[derive(Debug)]
pub struct StaticClient {
pub data: HashMap<String, String>,
}
impl HttpClient for StaticClient {
fn get(&self, url: &str) -> crate::web::Result<String> {
info!("Resolving {url} in static client");
Ok(self
.data
.get(url)
.unwrap_or_else(|| panic!("the url {url} should be defined"))
.to_string())
}
}