Skip to content

Commit

Permalink
initial testing of fsm
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam committed May 26, 2023
1 parent 774e54d commit 7e5d118
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions crates/analyzer-host/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ serde = "1.0.143"
serde_json = "1.0.83"
thiserror = "1.0.37"
tracing-subscriber = "0.3.16"

[dev-dependencies]
async-io = "1.13.0"
tester = { path = "../tester" }
6 changes: 5 additions & 1 deletion crates/analyzer-host/src/fsm.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use analyzer_abstractions::{fs::AnyEnumerableFileSystem, tracing::info};
use async_rwlock::RwLock as AsyncRwLock;
use serde_json::Value;
use std::{
collections::HashMap,
sync::{Arc, RwLock},
};

use crate::{
json_rpc::{message::Message, ErrorCode},
json_rpc::{message::{Message, Request, self, Notification}, ErrorCode},
lsp::{dispatch::Dispatch, request::RequestManager, state::LspServerState, DispatchBuilder, LspProtocolError},
lsp_impl::{
active_initialized::create_dispatcher as create_dispatcher_active_initialized,
Expand Down Expand Up @@ -52,6 +53,9 @@ impl LspProtocolMachine {
/// Returns `true` if the current [`LspProtocolMachine`] is in an active state; otherwise `false`.
pub fn is_active(&self) -> bool { self.current_state != LspServerState::Stopped }

/// Returns the current_state that the [`LspProtocolMachine`] is in.
pub fn current_state(&self) -> LspServerState { self.current_state }

/// Processes a [`Message`] for the current [`LspProtocolMachine`], and returns an optional [`Message`] that represents
/// its response.
pub async fn process_message(&mut self, message: Arc<Message>) -> Result<Option<Message>, LspProtocolError> {
Expand Down
4 changes: 4 additions & 0 deletions crates/analyzer-host/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,7 @@ impl AnalyzerHost {
Ok(())
}
}

// Unit test fixtures.
#[cfg(test)]
mod tests;
1 change: 1 addition & 0 deletions crates/analyzer-host/src/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub(crate) mod unit_tests;
70 changes: 70 additions & 0 deletions crates/analyzer-host/src/tests/unit_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use std::sync::Arc;

use analyzer_abstractions::lsp_types::{
Position, TextDocumentIdentifier, TextDocumentPositionParams, Url, WorkDoneProgressParams,
};
use serde_json::Value;

use crate::{
fs::LspEnumerableFileSystem,
fsm::LspProtocolMachine,
json_rpc::message::{Message, Notification, Request},
lsp::{request::RequestManager, state::LspServerState},
};

#[test]
fn test_lsp_states() {
let rm = RequestManager::new(async_channel::unbounded::<Message>());
let mut lsp =
LspProtocolMachine::new(None, rm.clone(), Arc::new(Box::new(LspEnumerableFileSystem::new(rm.clone()))));
assert_eq!(lsp.current_state(), LspServerState::ActiveUninitialized);
assert_eq!(lsp.is_active(), true);

let mut params = serde_json::json!(analyzer_abstractions::lsp_types::InitializeParams { ..Default::default() });
let mut message = Message::Request(Request { id: 0.into(), method: String::from("initialize"), params: params });
let mut output = async_io::block_on(lsp.process_message(Arc::new(message)));
assert!(output.is_ok());
assert_eq!(lsp.current_state(), LspServerState::Initializing);
assert_eq!(lsp.is_active(), true);

let url = Url::parse("https://example.net").unwrap();
let hover_params = analyzer_abstractions::lsp_types::HoverParams {
text_document_position_params: TextDocumentPositionParams {
text_document: TextDocumentIdentifier { uri: url },
position: Position { line: 0, character: 0 },
},
work_done_progress_params: WorkDoneProgressParams { work_done_token: None },
};
params = serde_json::json!(hover_params);
message = Message::Request(Request { id: 0.into(), method: String::from("textDocument/hover"), params: params });
output = async_io::block_on(lsp.process_message(Arc::new(message)));
assert!(output.is_ok());
assert_eq!(lsp.current_state(), LspServerState::Initializing);
assert_eq!(lsp.is_active(), true);

params = serde_json::json!(analyzer_abstractions::lsp_types::InitializedParams {});
message = Message::Notification(Notification { method: String::from("initialized"), params: params });
output = async_io::block_on(lsp.process_message(Arc::new(message)));
assert!(output.is_ok());
assert_eq!(lsp.current_state(), LspServerState::ActiveInitialized);
assert_eq!(lsp.is_active(), true);

params = serde_json::json!(hover_params);
message = Message::Notification(Notification { method: String::from("textDocument/hover"), params: params });
output = async_io::block_on(lsp.process_message(Arc::new(message)));
assert!(output.is_err());
assert_eq!(lsp.current_state(), LspServerState::ActiveInitialized);
assert_eq!(lsp.is_active(), true);

message = Message::Request(Request { id: 0.into(), method: String::from("shutdown"), params: Value::Null });
output = async_io::block_on(lsp.process_message(Arc::new(message)));
assert!(output.is_ok());
assert_eq!(lsp.current_state(), LspServerState::ShuttingDown);
assert_eq!(lsp.is_active(), true);

message = Message::Notification(Notification { method: String::from("exit"), params: Value::Null });
output = async_io::block_on(lsp.process_message(Arc::new(message)));
assert!(output.is_ok());
assert_eq!(lsp.current_state(), LspServerState::Stopped);
assert_eq!(lsp.is_active(), false);
}

0 comments on commit 7e5d118

Please sign in to comment.