termesh_test_support/
scripted_lsp.rs1use std::collections::VecDeque;
2use std::sync::{Arc, Mutex};
3
4use termesh_core::{LspEvent, LspRequest};
5use termesh_lsp::LanguageService;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum FakeLspCall {
9 Send(LspRequest),
10}
11
12#[derive(Clone)]
13pub struct FakeLspControl {
14 calls: Arc<Mutex<Vec<FakeLspCall>>>,
15}
16
17impl FakeLspControl {
18 pub fn calls(&self) -> Vec<FakeLspCall> {
19 self.calls.lock().expect("fake LSP call log poisoned").clone()
20 }
21}
22
23#[derive(Default)]
24pub struct ScriptedLanguageServer {
25 events: VecDeque<Vec<LspEvent>>,
26 calls: Arc<Mutex<Vec<FakeLspCall>>>,
27}
28
29impl ScriptedLanguageServer {
30 pub fn new() -> Self {
31 Self::default()
32 }
33
34 pub fn control(&self) -> FakeLspControl {
35 FakeLspControl { calls: self.calls.clone() }
36 }
37
38 pub fn with_events(mut self, events: Vec<LspEvent>) -> Self {
39 self.events.push_back(events);
40 self
41 }
42}
43
44impl LanguageService for ScriptedLanguageServer {
45 fn send(&mut self, request: LspRequest) {
46 self.calls.lock().expect("fake LSP call log poisoned").push(FakeLspCall::Send(request));
47 }
48
49 fn poll(&mut self) -> Vec<LspEvent> {
50 self.events.pop_front().unwrap_or_default()
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57 use termesh_core::{LspEvent, LspRequest};
58 use termesh_lsp::LanguageService;
59
60 #[test]
61 fn sends_are_recorded_in_order() {
62 let mut server = ScriptedLanguageServer::new();
63 let control = server.control();
64 server.send(LspRequest::Shutdown);
65 server.send(LspRequest::Shutdown);
66 assert_eq!(
67 control.calls(),
68 vec![FakeLspCall::Send(LspRequest::Shutdown), FakeLspCall::Send(LspRequest::Shutdown)]
69 );
70 }
71
72 #[test]
73 fn poll_replays_one_batch_at_a_time_then_returns_empty() {
74 let mut server = ScriptedLanguageServer::new()
75 .with_events(vec![LspEvent::Started])
76 .with_events(vec![LspEvent::Ready]);
77 assert_eq!(server.poll(), vec![LspEvent::Started]);
78 assert_eq!(server.poll(), vec![LspEvent::Ready]);
79 assert!(server.poll().is_empty());
80 assert!(server.poll().is_empty(), "an exhausted script is never a panic");
81 }
82}