commands_test.rs
1 use crate::harness::{LspTestClient, TempWorkspace}; 2 use serde_json::json; 3 use std::thread; 4 use std::time::Duration; 5 6 #[test] 7 fn test_command_list_env_variables() { 8 let workspace = TempWorkspace::new(); 9 let client = LspTestClient::spawn(workspace.root.clone()).expect("Failed to spawn LSP"); 10 client.initialize().expect("Initialize failed"); 11 12 let result = client 13 .execute_command("ecolog.listEnvVariables", vec![]) 14 .expect("Command execution failed"); 15 16 let variables = result 17 .get("variables") 18 .expect("Should have variables") 19 .as_array() 20 .expect("Variables should be array"); 21 22 assert!( 23 variables.len() >= 4, 24 "Should have at least 4 variables (DB_URL, API_KEY, DEBUG, PORT)" 25 ); 26 27 let names: Vec<&str> = variables 28 .iter() 29 .filter_map(|v| v.get("name")?.as_str()) 30 .collect(); 31 32 assert!(names.contains(&"DB_URL"), "Should have DB_URL"); 33 assert!(names.contains(&"API_KEY"), "Should have API_KEY"); 34 35 client.shutdown().expect("Shutdown failed"); 36 } 37 38 #[test] 39 fn test_command_file_list() { 40 let workspace = TempWorkspace::new(); 41 let client = LspTestClient::spawn(workspace.root.clone()).expect("Failed to spawn LSP"); 42 client.initialize().expect("Initialize failed"); 43 44 let result = client 45 .execute_command("ecolog.file.list", vec![]) 46 .expect("Command execution failed"); 47 48 let files = result 49 .get("files") 50 .expect("Should have files") 51 .as_array() 52 .expect("Files should be array"); 53 54 assert!( 55 files 56 .iter() 57 .any(|f| f.as_str().map(|s| s.contains(".env")).unwrap_or(false)), 58 "Should list .env file" 59 ); 60 61 client.shutdown().expect("Shutdown failed"); 62 } 63 64 #[test] 65 fn test_command_set_active_file() { 66 let workspace = TempWorkspace::new(); 67 workspace.create_file(".env.production", "MODE=production\n"); 68 69 let client = LspTestClient::spawn(workspace.root.clone()).expect("Failed to spawn LSP"); 70 client.initialize().expect("Initialize failed"); 71 72 thread::sleep(Duration::from_millis(300)); 73 74 let result = client 75 .execute_command("ecolog.file.setActive", vec![json!(".env.production")]) 76 .expect("Command execution failed"); 77 78 assert_eq!( 79 result.get("success"), 80 Some(&json!(true)), 81 "setActive should succeed" 82 ); 83 84 client.shutdown().expect("Shutdown failed"); 85 } 86 87 #[test] 88 fn test_command_get_variable() { 89 let workspace = TempWorkspace::new(); 90 let client = LspTestClient::spawn(workspace.root.clone()).expect("Failed to spawn LSP"); 91 client.initialize().expect("Initialize failed"); 92 93 let result = client 94 .execute_command("ecolog.variable.get", vec![json!("DB_URL")]) 95 .expect("Command execution failed"); 96 97 assert_eq!( 98 result.get("name").and_then(|n| n.as_str()), 99 Some("DB_URL"), 100 "Should return correct variable name" 101 ); 102 assert!( 103 result 104 .get("value") 105 .and_then(|v| v.as_str()) 106 .map(|s| s.contains("postgres")) 107 .unwrap_or(false), 108 "Should return correct value" 109 ); 110 111 client.shutdown().expect("Shutdown failed"); 112 } 113 114 #[test] 115 fn test_command_get_variable_not_found() { 116 let workspace = TempWorkspace::new(); 117 let client = LspTestClient::spawn(workspace.root.clone()).expect("Failed to spawn LSP"); 118 client.initialize().expect("Initialize failed"); 119 120 let result = client 121 .execute_command("ecolog.variable.get", vec![json!("NONEXISTENT_VAR")]) 122 .expect("Command execution failed"); 123 124 assert!( 125 result.is_null() || result.get("error").is_some() || result.get("value").is_none(), 126 "Nonexistent variable should indicate not found" 127 ); 128 129 client.shutdown().expect("Shutdown failed"); 130 } 131 132 #[test] 133 fn test_command_interpolation_toggle() { 134 let workspace = TempWorkspace::new(); 135 let client = LspTestClient::spawn(workspace.root.clone()).expect("Failed to spawn LSP"); 136 client.initialize().expect("Initialize failed"); 137 138 let result = client 139 .execute_command("ecolog.interpolation.set", vec![json!(false)]) 140 .expect("Command execution failed"); 141 142 assert_eq!(result.get("success"), Some(&json!(true))); 143 assert_eq!(result.get("enabled"), Some(&json!(false))); 144 145 let get_result = client 146 .execute_command("ecolog.interpolation.get", vec![]) 147 .expect("Command execution failed"); 148 149 assert_eq!(get_result.get("enabled"), Some(&json!(false))); 150 151 let result = client 152 .execute_command("ecolog.interpolation.set", vec![json!(true)]) 153 .expect("Command execution failed"); 154 155 assert_eq!(result.get("enabled"), Some(&json!(true))); 156 157 client.shutdown().expect("Shutdown failed"); 158 } 159 160 #[test] 161 fn test_command_workspace_list() { 162 let workspace = TempWorkspace::new(); 163 let client = LspTestClient::spawn(workspace.root.clone()).expect("Failed to spawn LSP"); 164 client.initialize().expect("Initialize failed"); 165 166 let result = client 167 .execute_command("ecolog.workspace.list", vec![]) 168 .expect("Command execution failed"); 169 170 assert!(!result.is_null(), "Should return workspace info"); 171 172 client.shutdown().expect("Shutdown failed"); 173 } 174 175 #[test] 176 fn test_command_workspace_set_root() { 177 let workspace = TempWorkspace::new(); 178 let subdir = workspace.root.join("subproject"); 179 std::fs::create_dir_all(&subdir).unwrap(); 180 std::fs::write(subdir.join(".env"), "SUB_VAR=value\n").unwrap(); 181 182 let client = LspTestClient::spawn(workspace.root.clone()).expect("Failed to spawn LSP"); 183 client.initialize().expect("Initialize failed"); 184 185 let result = client 186 .execute_command( 187 "ecolog.workspace.setRoot", 188 vec![json!(subdir.to_string_lossy())], 189 ) 190 .expect("Command execution failed"); 191 192 assert_eq!(result.get("success"), Some(&json!(true))); 193 194 client.shutdown().expect("Shutdown failed"); 195 } 196 197 #[test] 198 fn test_unknown_command_returns_null() { 199 let workspace = TempWorkspace::new(); 200 let client = LspTestClient::spawn(workspace.root.clone()).expect("Failed to spawn LSP"); 201 client.initialize().expect("Initialize failed"); 202 203 let result = client 204 .execute_command("ecolog.unknown.command", vec![]) 205 .expect("Command execution failed"); 206 207 assert!(result.is_null(), "Unknown command should return null"); 208 209 client.shutdown().expect("Shutdown failed"); 210 } 211 212 #[test] 213 fn test_command_generate_env_example() { 214 let workspace = TempWorkspace::new(); 215 workspace.create_file( 216 "app.js", 217 "const url = process.env.DB_URL;\nconst key = process.env.API_KEY;", 218 ); 219 220 let client = LspTestClient::spawn(workspace.root.clone()).expect("Failed to spawn LSP"); 221 client.initialize().expect("Initialize failed"); 222 223 let uri = workspace.file_uri("app.js"); 224 client 225 .open_document( 226 &uri, 227 "javascript", 228 "const url = process.env.DB_URL;\nconst key = process.env.API_KEY;", 229 ) 230 .expect("Failed to open document"); 231 232 thread::sleep(Duration::from_millis(500)); 233 234 let result = client 235 .execute_command("ecolog.generateEnvExample", vec![]) 236 .expect("Command execution failed"); 237 238 if !result.is_null() { 239 if let Some(content) = result.get("content").and_then(|c| c.as_str()) { 240 assert!(content.len() < 100000, "Content should be reasonable size"); 241 } 242 } 243 244 client.shutdown().expect("Shutdown failed"); 245 }