diff options
| author | diogo464 <[email protected]> | 2025-06-19 09:46:52 +0100 |
|---|---|---|
| committer | diogo464 <[email protected]> | 2025-06-19 09:46:52 +0100 |
| commit | 6a4e906586a043dff295be532d653f4635974502 (patch) | |
| tree | 4248bbdb6d3791d37ef8df42abc698f021a3e835 /tests/cli.rs | |
| parent | 03793fad36480273ebd702e80f41f4baf513647c (diff) | |
Make --id a positional argument for improved CLI usability
- Remove --id flags from all command argument structures
- Update RunArgs, StopArgs, TailArgs, CatArgs, StatusArgs to use positional ID
- Update all integration tests to use new positional argument syntax
- Update comprehensive LLM guide documentation with new command syntax
- Maintain -- separator support for complex commands
- More natural CLI interface: 'demon run web-server python -m http.server 8080'
- Consistent with common tools like docker, systemctl, git
- Breaking change but improves usability significantly
- All tests pass with new CLI format
Examples of new syntax:
- demon run web-server python -m http.server 8080
- demon stop web-server
- demon status web-server
- demon tail web-server --stdout
- demon cat web-server
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
Diffstat (limited to 'tests/cli.rs')
| -rw-r--r-- | tests/cli.rs | 41 |
1 files changed, 19 insertions, 22 deletions
diff --git a/tests/cli.rs b/tests/cli.rs index 2903f61..5e72dad 100644 --- a/tests/cli.rs +++ b/tests/cli.rs | |||
| @@ -35,7 +35,7 @@ fn test_run_missing_command() { | |||
| 35 | 35 | ||
| 36 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 36 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 37 | cmd.current_dir(temp_dir.path()) | 37 | cmd.current_dir(temp_dir.path()) |
| 38 | .args(&["run", "--id", "test"]) | 38 | .args(&["run", "test"]) |
| 39 | .assert() | 39 | .assert() |
| 40 | .failure() | 40 | .failure() |
| 41 | .stderr(predicate::str::contains("Command cannot be empty")); | 41 | .stderr(predicate::str::contains("Command cannot be empty")); |
| @@ -47,7 +47,7 @@ fn test_run_creates_files() { | |||
| 47 | 47 | ||
| 48 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 48 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 49 | cmd.current_dir(temp_dir.path()) | 49 | cmd.current_dir(temp_dir.path()) |
| 50 | .args(&["run", "--id", "test", "echo", "hello"]) | 50 | .args(&["run", "test", "echo", "hello"]) |
| 51 | .assert() | 51 | .assert() |
| 52 | .success() | 52 | .success() |
| 53 | .stdout(predicate::str::contains("Started daemon 'test'")); | 53 | .stdout(predicate::str::contains("Started daemon 'test'")); |
| @@ -72,14 +72,14 @@ fn test_run_duplicate_process() { | |||
| 72 | // Start a long-running process | 72 | // Start a long-running process |
| 73 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 73 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 74 | cmd.current_dir(temp_dir.path()) | 74 | cmd.current_dir(temp_dir.path()) |
| 75 | .args(&["run", "--id", "long", "sleep", "30"]) | 75 | .args(&["run", "long", "sleep", "30"]) |
| 76 | .assert() | 76 | .assert() |
| 77 | .success(); | 77 | .success(); |
| 78 | 78 | ||
| 79 | // Try to start another with the same ID | 79 | // Try to start another with the same ID |
| 80 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 80 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 81 | cmd.current_dir(temp_dir.path()) | 81 | cmd.current_dir(temp_dir.path()) |
| 82 | .args(&["run", "--id", "long", "sleep", "5"]) | 82 | .args(&["run", "long", "sleep", "5"]) |
| 83 | .assert() | 83 | .assert() |
| 84 | .failure() | 84 | .failure() |
| 85 | .stderr(predicate::str::contains("already running")); | 85 | .stderr(predicate::str::contains("already running")); |
| @@ -87,7 +87,7 @@ fn test_run_duplicate_process() { | |||
| 87 | // Clean up the running process | 87 | // Clean up the running process |
| 88 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 88 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 89 | cmd.current_dir(temp_dir.path()) | 89 | cmd.current_dir(temp_dir.path()) |
| 90 | .args(&["stop", "--id", "long"]) | 90 | .args(&["stop", "long"]) |
| 91 | .assert() | 91 | .assert() |
| 92 | .success(); | 92 | .success(); |
| 93 | } | 93 | } |
| @@ -114,7 +114,7 @@ fn test_list_with_processes() { | |||
| 114 | // Start a process | 114 | // Start a process |
| 115 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 115 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 116 | cmd.current_dir(temp_dir.path()) | 116 | cmd.current_dir(temp_dir.path()) |
| 117 | .args(&["run", "--id", "test", "echo", "done"]) | 117 | .args(&["run", "test", "echo", "done"]) |
| 118 | .assert() | 118 | .assert() |
| 119 | .success(); | 119 | .success(); |
| 120 | 120 | ||
| @@ -137,7 +137,6 @@ fn test_cat_output() { | |||
| 137 | cmd.current_dir(temp_dir.path()) | 137 | cmd.current_dir(temp_dir.path()) |
| 138 | .args(&[ | 138 | .args(&[ |
| 139 | "run", | 139 | "run", |
| 140 | "--id", | ||
| 141 | "test", | 140 | "test", |
| 142 | "--", | 141 | "--", |
| 143 | "sh", | 142 | "sh", |
| @@ -150,7 +149,7 @@ fn test_cat_output() { | |||
| 150 | // Cat the output | 149 | // Cat the output |
| 151 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 150 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 152 | cmd.current_dir(temp_dir.path()) | 151 | cmd.current_dir(temp_dir.path()) |
| 153 | .args(&["cat", "--id", "test"]) | 152 | .args(&["cat", "test"]) |
| 154 | .assert() | 153 | .assert() |
| 155 | .success() | 154 | .success() |
| 156 | .stdout(predicate::str::contains("stdout line")) | 155 | .stdout(predicate::str::contains("stdout line")) |
| @@ -166,7 +165,6 @@ fn test_cat_stdout_only() { | |||
| 166 | cmd.current_dir(temp_dir.path()) | 165 | cmd.current_dir(temp_dir.path()) |
| 167 | .args(&[ | 166 | .args(&[ |
| 168 | "run", | 167 | "run", |
| 169 | "--id", | ||
| 170 | "test", | 168 | "test", |
| 171 | "--", | 169 | "--", |
| 172 | "sh", | 170 | "sh", |
| @@ -179,7 +177,7 @@ fn test_cat_stdout_only() { | |||
| 179 | // Cat only stdout | 177 | // Cat only stdout |
| 180 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 178 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 181 | cmd.current_dir(temp_dir.path()) | 179 | cmd.current_dir(temp_dir.path()) |
| 182 | .args(&["cat", "--id", "test", "--stdout"]) | 180 | .args(&["cat", "test", "--stdout"]) |
| 183 | .assert() | 181 | .assert() |
| 184 | .success() | 182 | .success() |
| 185 | .stdout(predicate::str::contains("stdout line")) | 183 | .stdout(predicate::str::contains("stdout line")) |
| @@ -192,7 +190,7 @@ fn test_status_nonexistent() { | |||
| 192 | 190 | ||
| 193 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 191 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 194 | cmd.current_dir(temp_dir.path()) | 192 | cmd.current_dir(temp_dir.path()) |
| 195 | .args(&["status", "--id", "nonexistent"]) | 193 | .args(&["status", "nonexistent"]) |
| 196 | .assert() | 194 | .assert() |
| 197 | .success() | 195 | .success() |
| 198 | .stdout(predicate::str::contains("NOT FOUND")); | 196 | .stdout(predicate::str::contains("NOT FOUND")); |
| @@ -205,14 +203,14 @@ fn test_status_dead_process() { | |||
| 205 | // Create a short-lived process | 203 | // Create a short-lived process |
| 206 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 204 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 207 | cmd.current_dir(temp_dir.path()) | 205 | cmd.current_dir(temp_dir.path()) |
| 208 | .args(&["run", "--id", "dead", "echo", "hello"]) | 206 | .args(&["run", "dead", "echo", "hello"]) |
| 209 | .assert() | 207 | .assert() |
| 210 | .success(); | 208 | .success(); |
| 211 | 209 | ||
| 212 | // Check its status (should be dead) | 210 | // Check its status (should be dead) |
| 213 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 211 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 214 | cmd.current_dir(temp_dir.path()) | 212 | cmd.current_dir(temp_dir.path()) |
| 215 | .args(&["status", "--id", "dead"]) | 213 | .args(&["status", "dead"]) |
| 216 | .assert() | 214 | .assert() |
| 217 | .success() | 215 | .success() |
| 218 | .stdout(predicate::str::contains("DEAD")); | 216 | .stdout(predicate::str::contains("DEAD")); |
| @@ -224,7 +222,7 @@ fn test_stop_nonexistent() { | |||
| 224 | 222 | ||
| 225 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 223 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 226 | cmd.current_dir(temp_dir.path()) | 224 | cmd.current_dir(temp_dir.path()) |
| 227 | .args(&["stop", "--id", "nonexistent"]) | 225 | .args(&["stop", "nonexistent"]) |
| 228 | .assert() | 226 | .assert() |
| 229 | .success() | 227 | .success() |
| 230 | .stdout(predicate::str::contains("not running")); | 228 | .stdout(predicate::str::contains("not running")); |
| @@ -237,14 +235,14 @@ fn test_stop_process() { | |||
| 237 | // Start a long-running process | 235 | // Start a long-running process |
| 238 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 236 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 239 | cmd.current_dir(temp_dir.path()) | 237 | cmd.current_dir(temp_dir.path()) |
| 240 | .args(&["run", "--id", "long", "sleep", "10"]) | 238 | .args(&["run", "long", "sleep", "10"]) |
| 241 | .assert() | 239 | .assert() |
| 242 | .success(); | 240 | .success(); |
| 243 | 241 | ||
| 244 | // Stop it | 242 | // Stop it |
| 245 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 243 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 246 | cmd.current_dir(temp_dir.path()) | 244 | cmd.current_dir(temp_dir.path()) |
| 247 | .args(&["stop", "--id", "long"]) | 245 | .args(&["stop", "long"]) |
| 248 | .assert() | 246 | .assert() |
| 249 | .success() | 247 | .success() |
| 250 | .stdout(predicate::str::contains("terminated gracefully")); | 248 | .stdout(predicate::str::contains("terminated gracefully")); |
| @@ -272,7 +270,7 @@ fn test_clean_with_orphans() { | |||
| 272 | // Create a dead process | 270 | // Create a dead process |
| 273 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 271 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 274 | cmd.current_dir(temp_dir.path()) | 272 | cmd.current_dir(temp_dir.path()) |
| 275 | .args(&["run", "--id", "dead", "echo", "hello"]) | 273 | .args(&["run", "dead", "echo", "hello"]) |
| 276 | .assert() | 274 | .assert() |
| 277 | .success(); | 275 | .success(); |
| 278 | 276 | ||
| @@ -299,7 +297,6 @@ fn test_run_with_complex_command() { | |||
| 299 | cmd.current_dir(temp_dir.path()) | 297 | cmd.current_dir(temp_dir.path()) |
| 300 | .args(&[ | 298 | .args(&[ |
| 301 | "run", | 299 | "run", |
| 302 | "--id", | ||
| 303 | "complex", | 300 | "complex", |
| 304 | "--", | 301 | "--", |
| 305 | "sh", | 302 | "sh", |
| @@ -326,14 +323,14 @@ fn test_timeout_configuration() { | |||
| 326 | // Start a process | 323 | // Start a process |
| 327 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 324 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 328 | cmd.current_dir(temp_dir.path()) | 325 | cmd.current_dir(temp_dir.path()) |
| 329 | .args(&["run", "--id", "timeout-test", "sleep", "5"]) | 326 | .args(&["run", "timeout-test", "sleep", "5"]) |
| 330 | .assert() | 327 | .assert() |
| 331 | .success(); | 328 | .success(); |
| 332 | 329 | ||
| 333 | // Stop with custom timeout (should work normally since sleep responds to SIGTERM) | 330 | // Stop with custom timeout (should work normally since sleep responds to SIGTERM) |
| 334 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 331 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 335 | cmd.current_dir(temp_dir.path()) | 332 | cmd.current_dir(temp_dir.path()) |
| 336 | .args(&["stop", "--id", "timeout-test", "--timeout", "2"]) | 333 | .args(&["stop", "timeout-test", "--timeout", "2"]) |
| 337 | .assert() | 334 | .assert() |
| 338 | .success() | 335 | .success() |
| 339 | .stdout(predicate::str::contains("terminated gracefully")); | 336 | .stdout(predicate::str::contains("terminated gracefully")); |
| @@ -349,7 +346,7 @@ fn test_invalid_process_id() { | |||
| 349 | // Status should handle it gracefully | 346 | // Status should handle it gracefully |
| 350 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 347 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 351 | cmd.current_dir(temp_dir.path()) | 348 | cmd.current_dir(temp_dir.path()) |
| 352 | .args(&["status", "--id", "invalid"]) | 349 | .args(&["status", "invalid"]) |
| 353 | .assert() | 350 | .assert() |
| 354 | .success() | 351 | .success() |
| 355 | .stdout(predicate::str::contains("ERROR")); | 352 | .stdout(predicate::str::contains("ERROR")); |
| @@ -378,7 +375,7 @@ fn test_list_quiet_mode() { | |||
| 378 | // Create a process | 375 | // Create a process |
| 379 | let mut cmd = Command::cargo_bin("demon").unwrap(); | 376 | let mut cmd = Command::cargo_bin("demon").unwrap(); |
| 380 | cmd.current_dir(temp_dir.path()) | 377 | cmd.current_dir(temp_dir.path()) |
| 381 | .args(&["run", "--id", "quiet-test", "echo", "done"]) | 378 | .args(&["run", "quiet-test", "echo", "done"]) |
| 382 | .assert() | 379 | .assert() |
| 383 | .success(); | 380 | .success(); |
| 384 | 381 | ||
