Skip to main content

termesh_test_support/
scripted_lsp.rs

1use 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}