Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 44 additions & 74 deletions crates/coldvox-text-injection/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,94 +3,64 @@ use std::path::Path;
use std::process::Command;

fn main() {
// We only need to build the test applications if the `real-injection-tests` feature is enabled.
// This avoids adding build-time dependencies for regular users.
if env::var("CARGO_FEATURE_REAL_INJECTION_TESTS").is_ok() {
build_gtk_test_app();
build_terminal_test_app();
}
}

fn build_gtk_test_app() {
println!("cargo:rerun-if-changed=test-apps/gtk_test_app.c");

let out_dir = env::var("OUT_DIR").unwrap();
let executable_path = Path::new(&out_dir).join("gtk_test_app");

// Check if pkg-config and GTK3 are available before attempting to build.
let check_pkg_config = Command::new("pkg-config")
.arg("--atleast-version=3.0")
.arg("gtk+-3.0")
.status();

if check_pkg_config.is_err() || !check_pkg_config.unwrap().success() {
println!("cargo:warning=Skipping GTK test app build: GTK+ 3.0 not found by pkg-config.");
// Only run this build script if the `real-injection-tests` feature is enabled.
if env::var("CARGO_CFG_FEATURE_REAL_INJECTION_TESTS").is_err() {
println!("cargo:warning=Skipping build of test apps, real-injection-tests feature is not enabled.");
return;
}

// Get compiler flags from pkg-config.
let cflags_output = Command::new("pkg-config")
.arg("--cflags")
.arg("gtk+-3.0")
.output()
.expect("Failed to run pkg-config for cflags");
let out_dir = env::var("OUT_DIR").expect("OUT_DIR environment variable not set.");
let src_path = Path::new("test-apps").join("text-capture-app.c");

// Get linker flags from pkg-config.
let libs_output = Command::new("pkg-config")
.arg("--libs")
.arg("gtk+-3.0")
.output()
.expect("Failed to run pkg-config for libs");
// --- Compile GTK Test App ---
let gtk_app_out = Path::new(&out_dir).join("gtk_test_app");

let cflags = String::from_utf8(cflags_output.stdout).unwrap();
let libs = String::from_utf8(libs_output.stdout).unwrap();
// Use pkg-config to get GTK flags.
let gtk_cflags = pkg_config::Config::new().probe("gtk+-3.0").unwrap();
let mut command = Command::new("cc");
command.arg("-o").arg(&gtk_app_out);
for flag in &gtk_cflags.cflags {
command.arg(flag);
}
command.arg(&src_path);
for lib_path in &gtk_cflags.link_paths {
command.arg(format!("-L{}", lib_path.to_string_lossy()));
}
for lib in &gtk_cflags.libs {
command.arg(format!("-l{}", lib));
}

// Compile the test app using gcc.
let status = Command::new("gcc")
.arg("test-apps/gtk_test_app.c")
.arg("-o")
.arg(&executable_path)
.args(cflags.split_whitespace())
.args(libs.split_whitespace())
let status = command
.status()
.expect("Failed to execute gcc");
.expect("Failed to compile GTK test app with cc. Is a C compiler and GTK dev libraries installed?");

if !status.success() {
println!("cargo:warning=Failed to compile GTK test app. Real injection tests against GTK may fail.");
panic!("Failed to compile the GTK test app.");
}
}

fn build_terminal_test_app() {
println!("cargo:rerun-if-changed=test-apps/terminal-test-app/src/main.rs");
println!("cargo:rerun-if-changed=test-apps/terminal-test-app/Cargo.toml");

let out_dir = env::var("OUT_DIR").unwrap();
let target_dir = Path::new(&out_dir).join("terminal-test-app-target");
println!(
"cargo:warning=Successfully compiled GTK test app to: {:?}",
gtk_app_out
);

// Build the terminal test app using `cargo build`.
let status = Command::new(env::var("CARGO").unwrap_or_else(|_| "cargo".to_string()))
.arg("build")
.arg("--package")
.arg("terminal-test-app")
.arg("--release") // Build in release mode for faster startup.
.arg("--target-dir")
.arg(&target_dir)
// --- Compile Terminal Test App ---
let term_app_out = Path::new(&out_dir).join("terminal_test_app");
let status = Command::new("cc")
.arg("-o")
.arg(&term_app_out)
.arg("-DTERMINAL_MODE")
.arg(&src_path)
.status()
.expect("Failed to execute cargo build for terminal-test-app");
.expect("Failed to compile terminal test app with cc. Is a C compiler installed?");

if !status.success() {
println!(
"cargo:warning=Failed to build the terminal test app. Real injection tests may fail."
);
} else {
// Copy the executable to a known location in OUT_DIR for the tests to find easily.
let src_path = target_dir.join("release/terminal-test-app");
let dest_path = Path::new(&out_dir).join("terminal-test-app");
if let Err(e) = std::fs::copy(&src_path, &dest_path) {
println!(
"cargo:warning=Failed to copy terminal test app executable from {:?} to {:?}: {}",
src_path, dest_path, e
);
}
panic!("Failed to compile the terminal test app.");
}

println!(
"cargo:warning=Successfully compiled terminal test app to: {:?}",
term_app_out
);

println!("cargo:rerun-if-changed=test-apps/text-capture-app.c");
}
20 changes: 15 additions & 5 deletions crates/coldvox-text-injection/src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
//! Test modules for coldvox-text-injection
// The `real-injection-tests` feature enables tests that interact with a live desktop environment.
// These tests are disabled by default as they require a graphical session (X11 or Wayland).
// To run these tests: `cargo test -p coldvox-text-injection --features real-injection-tests`
#[cfg(feature = "real-injection-tests")]
pub mod real_injection;

// pub mod real_injection;
// Shared test utilities for both unit and real injection tests.
pub mod test_harness;
pub mod test_utils;
pub mod wl_copy_basic_test;
pub mod wl_copy_simple_test;
pub mod wl_copy_stdin_test;

// Unit tests for wl-clipboard-rs integration
#[cfg(feature = "wl_clipboard")]
mod wl_copy_basic_test;
#[cfg(feature = "wl_clipboard")]
mod wl_copy_simple_test;
#[cfg(feature = "wl_clipboard")]
mod wl_copy_stdin_test;
Loading
Loading