Files
ghostty-rs/crates/ghostty-lib/tests/c_host.rs
T
ddidderr a9f3856b15 fix: Windows core build, embedded init, byte-exact paths, version info
Closes the remaining core/lib/termio/GTK rows (final-Z2.md):
- ghostty-core compiles for Windows (Unix-only exec fields and file
  modes gated); checked with cargo check --target x86_64-pc-windows-gnu.
- Embedded init: ensure_locale, SIGPIPE ignored in ghostty_init for
  C/Swift hosts, Apple crash tags; the argv passed to ghostty_init feeds
  ghostty_config_load_cli_args; ghostty_config_load_file accepts
  non-UTF-8 paths.
- OSC 7 pwd, embedded surface cwd/command/env/initial input,
  ghostty_surface_text and GTK file drops keep raw bytes.
- XTVERSION, TERM_PROGRAM_VERSION, the About dialog and crash metadata
  use ghostty_build_info instead of hardcoded versions.

Test Plan:
- cargo test --workspace (3327 passed)
- cargo clippy --workspace --all-targets -- -D warnings
2026-10-12 08:14:02 +02:00

88 lines
2.6 KiB
Rust

//! Functional test: a C program using the unchanged `ghostty.h` (init,
//! CLI actions, config get/load/finalize/diagnostics, app lifecycle,
//! key bindings, actions callback) compiled with `cc` and linked against
//! the built `libghostty`.
#![cfg(unix)]
#![allow(clippy::unwrap_used)]
mod common;
use std::{path::PathBuf, process::Command};
fn host() -> PathBuf {
static ONCE: std::sync::OnceLock<PathBuf> = std::sync::OnceLock::new();
ONCE.get_or_init(|| {
let lib_dir = common::build_lib();
let dir = common::scratch_dir("host");
let exe = dir.join("host");
let src = common::manifest_dir().join("tests/c/host.c");
common::compile_c(&lib_dir, &[&src], &exe, &["-Wall", "-Wextra", "-pthread"]);
exe
})
.clone()
}
fn run(args: &[&str]) -> std::process::Output {
let dir = tempfile::tempdir().unwrap();
Command::new(host())
.args(args)
.env("XDG_CONFIG_HOME", dir.path())
.env("HOME", dir.path())
.env_remove("GHOSTTY_LOG")
.output()
.unwrap()
}
#[test]
fn host_program_passes() {
let out = run(&[]);
let stdout = String::from_utf8_lossy(&out.stdout);
let stderr = String::from_utf8_lossy(&out.stderr);
assert!(
out.status.success(),
"host failed\nstdout:\n{stdout}\nstderr:\n{stderr}"
);
assert!(stdout.contains("OK"), "stdout:\n{stdout}");
assert!(
stdout.contains(&format!("version={}", ghostty_build_info::VERSION_STRING)),
"stdout:\n{stdout}"
);
}
#[test]
fn cli_try_action_runs_version_and_exits() {
let out = run(&["+version"]);
let stdout = String::from_utf8_lossy(&out.stdout);
assert!(
out.status.success(),
"stderr: {}",
String::from_utf8_lossy(&out.stderr)
);
assert!(
stdout.starts_with(&format!("Ghostty {}", ghostty_build_info::VERSION_STRING)),
"stdout:\n{stdout}"
);
// The action ran instead of the rest of the program.
assert!(!stdout.contains("OK"));
}
#[test]
fn cli_try_action_runs_other_actions() {
let out = run(&["+list-keybinds"]);
assert!(out.status.success());
let stdout = String::from_utf8_lossy(&out.stdout);
assert!(stdout.contains("new_window"), "stdout:\n{stdout}");
let out = run(&["+list-actions"]);
assert!(out.status.success());
assert!(String::from_utf8_lossy(&out.stdout).contains("new_window"));
}
#[test]
fn init_rejects_multiple_actions() {
let out = run(&["+version", "+help"]);
// ghostty_init fails with a non-zero code, which the host CHECKs; the
// program then still runs on.
assert!(!out.status.success());
}