aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-07-10 17:11:50 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-07-10 17:28:31 +0300
commit3e8f9df14e6dd08a8d80d920b923870a80649f0b (patch)
treeea854ca617d1ca21a09d1e7aa9246ffc5f6e842b /tests
parent66be0b655fe922867f1eed100a41d67038b6ffd6 (diff)
fix: improve config diagnostic delivery
Diffstat (limited to 'tests')
-rw-r--r--tests/cli_wrapper.rs73
-rw-r--r--tests/client_mode.rs14
2 files changed, 82 insertions, 5 deletions
diff --git a/tests/cli_wrapper.rs b/tests/cli_wrapper.rs
index ea268f22..324efb03 100644
--- a/tests/cli_wrapper.rs
+++ b/tests/cli_wrapper.rs
@@ -2367,6 +2367,79 @@ fn worktree_open_existing_checkout_by_path_and_branch() {
}
#[test]
+fn config_check_reports_invalid_config_without_server() {
+ let base = unique_test_dir();
+ let config_home = base.join("config");
+ let runtime_dir = base.join("runtime");
+ let config_dir = config_home.join(app_dir_name());
+ fs::create_dir_all(&config_dir).unwrap();
+ fs::write(
+ config_dir.join("config.toml"),
+ "[keys\nnew_workspace = \"g\"\n",
+ )
+ .unwrap();
+
+ let checked = run_named_cli(&config_home, &runtime_dir, &["config", "check"]);
+
+ assert_eq!(checked.status.code(), Some(1));
+ assert!(
+ checked.stderr.is_empty(),
+ "stderr: {}",
+ String::from_utf8_lossy(&checked.stderr)
+ );
+ let stdout = String::from_utf8_lossy(&checked.stdout);
+ assert!(stdout.contains("config: issues found"), "{stdout}");
+ assert!(stdout.contains("TOML parse error"), "{stdout}");
+ assert!(stdout.contains("line 1"), "{stdout}");
+
+ fs::write(
+ config_dir.join("config.toml"),
+ "[ui]\nsidebar_min_width = 50\nsidebar_max_width = 30\n",
+ )
+ .unwrap();
+ let checked = run_named_cli(&config_home, &runtime_dir, &["config", "check"]);
+ let stdout = String::from_utf8_lossy(&checked.stdout);
+ assert_eq!(checked.status.code(), Some(1));
+ assert!(stdout.contains("sidebar_min_width (50)"), "{stdout}");
+ assert!(stdout.contains("sidebar_max_width (30)"), "{stdout}");
+
+ cleanup_test_base(&base);
+}
+
+#[test]
+fn config_check_reports_ok_when_config_is_missing() {
+ let base = unique_test_dir();
+ let config_home = base.join("config");
+ let runtime_dir = base.join("runtime");
+
+ let checked = run_named_cli(&config_home, &runtime_dir, &["config", "check"]);
+
+ assert!(checked.status.success());
+ let stdout = String::from_utf8_lossy(&checked.stdout);
+ assert!(stdout.contains("config: ok"), "{stdout}");
+
+ cleanup_test_base(&base);
+}
+
+#[test]
+fn config_check_rejects_json_output() {
+ let base = unique_test_dir();
+ let config_home = base.join("config");
+ let runtime_dir = base.join("runtime");
+
+ let checked = run_named_cli(&config_home, &runtime_dir, &["config", "check", "--json"]);
+
+ assert_eq!(checked.status.code(), Some(2));
+ assert!(checked.stdout.is_empty());
+ assert_eq!(
+ String::from_utf8_lossy(&checked.stderr),
+ "usage: herdr config check\n"
+ );
+
+ cleanup_test_base(&base);
+}
+
+#[test]
fn worktree_cli_rejects_local_argument_errors_before_socket_use() {
let base = unique_test_dir();
fs::create_dir_all(&base).unwrap();
diff --git a/tests/client_mode.rs b/tests/client_mode.rs
index 016d220e..21978d51 100644
--- a/tests/client_mode.rs
+++ b/tests/client_mode.rs
@@ -266,9 +266,9 @@ fn read_next_frame_payload(stream: &mut UnixStream, timeout: Duration) -> Result
Err("timed out waiting for Frame message".into())
}
-fn frame_contains_text(frame: &FrameWire, needle: &str) -> bool {
+fn frame_text(frame: &FrameWire) -> String {
if frame.cells.is_empty() {
- return false;
+ return String::new();
}
let width = frame.width.max(1) as usize;
@@ -285,7 +285,7 @@ fn frame_contains_text(frame: &FrameWire, needle: &str) -> bool {
let _ = (cursor.x, cursor.y, cursor.visible, cursor.shape);
}
- text.contains(needle)
+ text
}
// ---------------------------------------------------------------------------
@@ -391,11 +391,15 @@ fn client_sees_headless_startup_config_diagnostic() {
.unwrap();
let deadline = Instant::now() + Duration::from_secs(5);
let mut found_diagnostic = false;
+ let mut last_frame_text = String::new();
while Instant::now() < deadline {
match read_server_message(&mut stream) {
Ok((1, payload)) => {
let frame = decode_frame_payload(&payload).expect("decode frame");
- if frame_contains_text(&frame, "config parse error") {
+ last_frame_text = frame_text(&frame);
+ if last_frame_text.contains("config.toml")
+ && last_frame_text.contains("herdr config check")
+ {
found_diagnostic = true;
break;
}
@@ -407,7 +411,7 @@ fn client_sees_headless_startup_config_diagnostic() {
assert!(
found_diagnostic,
- "attached client should see startup config parse diagnostic"
+ "attached client should see startup config parse diagnostic; last frame:\n{last_frame_text}"
);
cleanup_spawned_herdr(spawned, base);