/ tests / e2e / lifecycle_test.rs
lifecycle_test.rs
  1  use crate::harness::{LspTestClient, TempWorkspace};
  2  use serde_json::json;
  3  
  4  #[test]
  5  fn test_initialize_response_capabilities() {
  6      let workspace = TempWorkspace::new();
  7      let client = LspTestClient::spawn(workspace.root.clone()).expect("Failed to spawn LSP");
  8  
  9      let result = client.initialize().expect("Initialize failed");
 10  
 11      let capabilities = result.get("capabilities").expect("Missing capabilities");
 12  
 13      assert!(
 14          capabilities.get("hoverProvider").is_some(),
 15          "Missing hoverProvider"
 16      );
 17      assert!(
 18          capabilities.get("completionProvider").is_some(),
 19          "Missing completionProvider"
 20      );
 21      assert!(
 22          capabilities.get("definitionProvider").is_some(),
 23          "Missing definitionProvider"
 24      );
 25      assert!(
 26          capabilities.get("referencesProvider").is_some(),
 27          "Missing referencesProvider"
 28      );
 29      assert!(
 30          capabilities.get("renameProvider").is_some(),
 31          "Missing renameProvider"
 32      );
 33  
 34      let rename = capabilities.get("renameProvider").unwrap();
 35      assert_eq!(rename.get("prepareProvider"), Some(&json!(true)));
 36  
 37      let sync = capabilities.get("textDocumentSync").unwrap();
 38      assert_eq!(
 39          sync.as_i64(),
 40          Some(2),
 41          "Expected TextDocumentSyncKind::INCREMENTAL"
 42      );
 43  
 44      let commands = capabilities
 45          .get("executeCommandProvider")
 46          .expect("Missing executeCommandProvider")
 47          .get("commands")
 48          .expect("Missing commands")
 49          .as_array()
 50          .expect("Commands should be array");
 51  
 52      assert!(
 53          commands.iter().any(|c| c == "ecolog.file.setActive"),
 54          "Missing ecolog.file.setActive command"
 55      );
 56      assert!(
 57          commands.iter().any(|c| c == "ecolog.listEnvVariables"),
 58          "Missing ecolog.listEnvVariables command"
 59      );
 60  
 61      client.shutdown().expect("Shutdown failed");
 62  }
 63  
 64  #[test]
 65  fn test_shutdown_and_exit() {
 66      let workspace = TempWorkspace::new();
 67      let client = LspTestClient::spawn(workspace.root.clone()).expect("Failed to spawn LSP");
 68  
 69      client.initialize().expect("Initialize failed");
 70  
 71      let result = client.request("shutdown", None);
 72      assert!(result.is_ok(), "Shutdown request failed");
 73  
 74      let _ = client.notify("exit", None);
 75  
 76      std::thread::sleep(std::time::Duration::from_millis(100));
 77  }
 78  
 79  #[test]
 80  fn test_initialization_trigger_characters() {
 81      let workspace = TempWorkspace::new();
 82      let client = LspTestClient::spawn(workspace.root.clone()).expect("Failed to spawn LSP");
 83  
 84      let result = client.initialize().expect("Initialize failed");
 85  
 86      let capabilities = result.get("capabilities").expect("Missing capabilities");
 87      let completion = capabilities
 88          .get("completionProvider")
 89          .expect("Missing completionProvider");
 90      let triggers = completion.get("triggerCharacters");
 91  
 92      assert!(triggers.is_some(), "Should have triggerCharacters");
 93      let triggers = triggers
 94          .unwrap()
 95          .as_array()
 96          .expect("triggerCharacters should be array");
 97  
 98      assert!(
 99          triggers.iter().any(|t| t == "."),
100          "Should include '.' as trigger character"
101      );
102  
103      client.shutdown().expect("Shutdown failed");
104  }
105  
106  #[test]
107  fn test_double_initialize_fails() {
108      let workspace = TempWorkspace::new();
109      let client = LspTestClient::spawn(workspace.root.clone()).expect("Failed to spawn LSP");
110  
111      client.initialize().expect("First initialize failed");
112  
113      let result = client.request(
114          "initialize",
115          Some(json!({
116              "processId": std::process::id(),
117              "rootUri": format!("file://{}", workspace.root.display()),
118              "capabilities": {}
119          })),
120      );
121  
122      assert!(result.is_err(), "Second initialize should fail");
123  
124      client.shutdown().expect("Shutdown failed");
125  }