resume_slash_commands.rs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. use std::fs;
  2. use std::path::PathBuf;
  3. use std::process::Command;
  4. use std::sync::atomic::{AtomicU64, Ordering};
  5. use std::time::{SystemTime, UNIX_EPOCH};
  6. use runtime::Session;
  7. static TEMP_COUNTER: AtomicU64 = AtomicU64::new(0);
  8. #[test]
  9. fn resumed_binary_accepts_slash_commands_with_arguments() {
  10. let temp_dir = unique_temp_dir("resume-slash-commands");
  11. fs::create_dir_all(&temp_dir).expect("temp dir should exist");
  12. let session_path = temp_dir.join("session.jsonl");
  13. let export_path = temp_dir.join("notes.txt");
  14. let mut session = Session::new();
  15. session
  16. .push_user_text("ship the slash command harness")
  17. .expect("session write should succeed");
  18. session
  19. .save_to_path(&session_path)
  20. .expect("session should persist");
  21. let output = Command::new(env!("CARGO_BIN_EXE_claw"))
  22. .current_dir(&temp_dir)
  23. .args([
  24. "--resume",
  25. session_path.to_str().expect("utf8 path"),
  26. "/export",
  27. export_path.to_str().expect("utf8 path"),
  28. "/clear",
  29. "--confirm",
  30. ])
  31. .output()
  32. .expect("claw should launch");
  33. assert!(
  34. output.status.success(),
  35. "stdout:\n{}\n\nstderr:\n{}",
  36. String::from_utf8_lossy(&output.stdout),
  37. String::from_utf8_lossy(&output.stderr)
  38. );
  39. let stdout = String::from_utf8(output.stdout).expect("stdout should be utf8");
  40. assert!(stdout.contains("Export"));
  41. assert!(stdout.contains("wrote transcript"));
  42. assert!(stdout.contains(export_path.to_str().expect("utf8 path")));
  43. assert!(stdout.contains("Cleared resumed session file"));
  44. let export = fs::read_to_string(&export_path).expect("export file should exist");
  45. assert!(export.contains("# Conversation Export"));
  46. assert!(export.contains("ship the slash command harness"));
  47. let restored = Session::load_from_path(&session_path).expect("cleared session should load");
  48. assert!(restored.messages.is_empty());
  49. }
  50. fn unique_temp_dir(label: &str) -> PathBuf {
  51. let millis = SystemTime::now()
  52. .duration_since(UNIX_EPOCH)
  53. .expect("clock should be after epoch")
  54. .as_millis();
  55. let counter = TEMP_COUNTER.fetch_add(1, Ordering::Relaxed);
  56. std::env::temp_dir().join(format!(
  57. "claw-{label}-{}-{millis}-{counter}",
  58. std::process::id()
  59. ))
  60. }